Skip to content

Commit c43c2d3

Browse files
Use channels instead of mutexes
1 parent b647447 commit c43c2d3

File tree

1 file changed

+55
-29
lines changed

1 file changed

+55
-29
lines changed

rpi-timelapse/src/timelapse-camera.go

+55-29
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"bytes"
45
"fmt"
56
"io"
67
"log"
@@ -12,13 +13,19 @@ import (
1213
)
1314

1415
type TimelapseCamera struct {
15-
Store *TimelapseStore
16-
CurrentTicker *time.Ticker
17-
Mutex sync.Mutex
16+
Store *TimelapseStore
17+
CurrentTicker *time.Ticker
18+
Mutex sync.Mutex
19+
RequestsChannel chan<- *CameraSettings
20+
ResponsesChannel <-chan *bytes.Reader
1821
}
1922

2023
func (tt *TimelapseCamera) StartTimelapse(t *TimelapseSettings) {
2124

25+
reqs, res := tt.CameraServer()
26+
tt.RequestsChannel = reqs
27+
tt.ResponsesChannel = res
28+
2229
if tt.CurrentTicker != nil {
2330
tt.CurrentTicker.Stop()
2431
tt.CurrentTicker = nil
@@ -43,33 +50,52 @@ func (tt *TimelapseCamera) StartTimelapse(t *TimelapseSettings) {
4350

4451
}
4552

46-
func (c *TimelapseCamera) CaptureImage(cameraSettings *CameraSettings, w io.Writer) {
47-
log.Printf("Camera settings for capture: %+v", cameraSettings)
48-
s := raspicam.NewStill()
49-
s.Camera.VFlip = cameraSettings.VFlip
50-
s.Camera.HFlip = cameraSettings.HFlip
51-
s.Camera.Rotation = cameraSettings.Rotation
52-
s.Camera.MeteringMode = raspicam.MeteringAverage
53-
s.Camera.AWBMode = raspicam.AWBOff
54-
s.Camera.ISO = 200
55-
s.Args = []string{"--flicker", "50hz", "-awbg", "1.7,1.9", "--drc", "high"}
56-
s.Width = cameraSettings.Width
57-
s.Height = cameraSettings.Height
58-
s.Encoding = raspicam.EncodingPNG
59-
s.Timeout = time.Duration(1) * time.Minute
60-
61-
errCh := make(chan error)
53+
func (c *TimelapseCamera) CameraServer() (requests chan<- *CameraSettings, responses <-chan *bytes.Reader) {
54+
reqs := make(chan *CameraSettings, 1)
55+
ress := make(chan *bytes.Reader, 1)
56+
6257
go func() {
63-
for x := range errCh {
64-
fmt.Fprintf(os.Stderr, "%v\n", x)
58+
for cameraSettings := range reqs {
59+
60+
s := raspicam.NewStill()
61+
s.Camera.VFlip = cameraSettings.VFlip
62+
s.Camera.HFlip = cameraSettings.HFlip
63+
s.Camera.Rotation = cameraSettings.Rotation
64+
s.Camera.MeteringMode = raspicam.MeteringAverage
65+
s.Camera.AWBMode = raspicam.AWBOff
66+
s.Camera.ISO = 200
67+
s.Args = []string{"--flicker", "50hz", "-awbg", "1.7,1.9", "--drc", "high"}
68+
s.Width = cameraSettings.Width
69+
s.Height = cameraSettings.Height
70+
s.Encoding = raspicam.EncodingPNG
71+
72+
errCh := make(chan error)
73+
go func() {
74+
for x := range errCh {
75+
fmt.Fprintf(os.Stderr, "%v\n", x)
76+
}
77+
}()
78+
79+
var b *bytes.Buffer = &bytes.Buffer{}
80+
log.Println("Capturing image")
81+
raspicam.Capture(s, b, errCh)
82+
log.Println("Returning image")
83+
ress <- bytes.NewReader(b.Bytes())
6584
}
6685
}()
67-
c.Mutex.Lock()
68-
log.Println("Reserved camera - taking photo")
69-
defer func() {
70-
c.Mutex.Unlock()
71-
log.Println("Freed camera")
72-
}()
73-
raspicam.Capture(s, w, errCh)
74-
log.Println("Finished taking photo")
86+
87+
return reqs, ress
88+
}
89+
90+
func (c *TimelapseCamera) CaptureImage(cameraSettings *CameraSettings, w io.Writer) {
91+
92+
log.Println("Requesting image")
93+
c.RequestsChannel <- cameraSettings
94+
reader := <-c.ResponsesChannel
95+
log.Println("Receiving image")
96+
_, err := io.Copy(w, reader)
97+
if err != nil {
98+
log.Printf("Error copying %s", err.Error())
99+
}
100+
75101
}

0 commit comments

Comments
 (0)