Skip to content

Commit b2ff2e6

Browse files
committed
Final version camera guide
1 parent 6ca3d45 commit b2ff2e6

File tree

2 files changed

+21
-195
lines changed

2 files changed

+21
-195
lines changed
Loading

content/hardware/08.mega/boards/giga-r1/tutorials/giga-camera/giga-camera.md

Lines changed: 21 additions & 195 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,29 @@
11
---
22
title: GIGA R1 Camera Guide
3-
description: Learn about GIGA R1 and camera compatibility, and find examples that work out of the box with the GIGA R1.
4-
tags: [ArduCAM, Camera, AI, OpenMV]
3+
description: Learn about the GIGA R1 & GIGA R1 WiFi's camera connector, and how to use existing examples.
4+
tags: [ArduCAM, Camera, Processing]
55
author: Karl Söderby
66
---
77

88
The GIGA R1 has a dedicated camera connector that allows certain camera modules to mount directly on the board. This makes it possible to add machine vision to your GIGA R1 board without much effort at all.
99

10-
In this guide, we will explore the GIGA R1's camera support a bit more in-depth:
10+
In this guide, we will explore the following:
1111

1212
- Where the camera connector is located.
1313
- What cameras are compatible.
14-
- What library/examples are available.
15-
- How to get started with machine vision using the OpenMV platform.
14+
- What library to use.
15+
- How to setup a camera stream to a processing application.
1616

17-
## Hardware Requirements
17+
## Hardware & Software Needed
1818

1919
To follow and use the examples provided in this guide, you will need one of the following boards:
2020

21-
- [GIGA R1]()
22-
- [GIGA R1 WiFi]()
21+
- [GIGA R1](/hardware/giga-r1)
22+
- [GIGA R1 WiFi](/hardware/giga-r1-wifi)
23+
24+
You will also need the following software:
25+
- [Arduino IDE](https://www.arduino.cc/en/software) (any version).
26+
- [Processing](https://processing.org/download) (for displaying camera feed).
2327

2428
## Supported Cameras
2529

@@ -57,19 +61,19 @@ The complete pin map can be found below:
5761

5862
![Camera connector, zoomed in.](assets/camera-connector-zoomed.png)
5963

60-
## OpenMV
64+
You can also view the schematic for this connector in more detail just below. This is useful to understand exactly which pins on the STM32H747XI microcontroller is used.
6165

62-
[OpenMV](https://openmv.io/) is a platform for machine vision projects, and can be programmed with MicroPython, more specifically, [OpenMV's branch of MicroPython](https://github.com/openmv/micropython).
66+
![Schematic for Camera Connector (J6).](assets/camera-schematic.png)
6367

6468
## Raw Bytes Over Serial (Processing)
6569

6670
![Live view of the camera.](assets/processing-example.png)
6771

68-
This example allows you to stream the sensor data from your camera to a Processing application, using serial over USB. This will allow you to see the image directly in your computer.
72+
This example allows you to stream the sensor data from your camera to a Processing application, using serial over USB. This will allow you to see the image directly in your computer.
6973

7074
***This example requires a version of [Processing](https://processing.org/download) on your machine.***
7175

72-
**Step 1: Arduino**
76+
### Step 1: Arduino
7377

7478
Upload the following sketch to your board.
7579

@@ -151,13 +155,13 @@ void loop() {
151155
152156
```
153157

154-
**Step 2: Processing**
158+
### Step 2: Processing
155159

156-
The following processing sketch will launch a Java app that allows you to view the camera. As data is streamed via serial, make sure you close the Serial Monitor during this process, else it won't work.
160+
The following Processing sketch will launch a Java app that allows you to view the camera feed. As data is streamed via serial, make sure you close the Serial Monitor during this process, else it will not work.
157161

158162
***Important! Make sure to replace the following line in the code below: `/dev/cu.usbmodem14301`, with the name of your port.***
159163

160-
Click on the big "PLAY" button to initialize the app.
164+
Click on the **"PLAY"** button to initialize the app.
161165

162166
```cpp
163167
/*
@@ -283,184 +287,6 @@ void serialEvent(Serial myPort) {
283287
284288
If all goes well, you should now be able to see the camera feed.
285289
286-
### JPEG Webserver
287-
288-
The **JPEG Webserver** allows you to take an image every X amount of seconds and upload it to a webserver that can be accessed remotely. This setup can be used for asset monitoring, security systems, smart doorbells and many more applications.
289-
290-
This setup also comes with a Golang script that you will need to launch via a terminal, which is required to make this setup work.
291-
292-
**Step 1: Launch Golang Script**
293-
294-
First, create a file in a directory of your choice, and name it `main.go`. Paste the following code into it:
295-
296-
```go
297-
package main
298-
299-
import (
300-
"fmt"
301-
"io/ioutil"
302-
"net/http"
303-
"strconv"
304-
"time"
305-
)
306-
307-
func uploadFile(w http.ResponseWriter, r *http.Request) {
308-
fmt.Println("File Upload Endpoint Hit")
309-
310-
// Parse our multipart form, 10 << 20 specifies a maximum
311-
// upload of 10 MB files.
312-
r.ParseMultipartForm(10 << 20)
313-
// FormFile returns the first file for the given key `myFile`
314-
// it also returns the FileHeader so we can get the Filename,
315-
// the Header and the size of the file
316-
file, handler, err := r.FormFile("image1")
317-
if err != nil {
318-
fmt.Println("Error Retrieving the File")
319-
fmt.Println(err)
320-
return
321-
}
322-
defer file.Close()
323-
fmt.Printf("Uploaded File: %+v\n", handler.Filename)
324-
fmt.Printf("File Size: %+v\n", handler.Size)
325-
fmt.Printf("MIME Header: %+v\n", handler.Header)
326-
327-
// Create a temporary file within our temp-images directory that follows
328-
// a particular naming pattern
329-
name := "upload-" + strconv.Itoa(int(time.Now().Unix())) + "*.jpg"
330-
tempFile, err := ioutil.TempFile("", name)
331-
if err != nil {
332-
fmt.Println(err)
333-
}
334-
defer tempFile.Close()
335-
fmt.Println("File ", tempFile.Name())
336-
337-
// read all of the contents of our uploaded file into a
338-
// byte array
339-
fileBytes, err := ioutil.ReadAll(file)
340-
if err != nil {
341-
fmt.Println(err)
342-
}
343-
// write this byte array to our temporary file
344-
tempFile.Write(fileBytes)
345-
// return that we have successfully uploaded our file!
346-
fmt.Println("Successfully Uploaded File\n")
347-
}
348-
349-
func setupRoutes() {
350-
http.HandleFunc("/upload", uploadFile)
351-
http.ListenAndServe(":8088", nil)
352-
}
353-
354-
func main() {
355-
fmt.Println("Hello World")
356-
fmt.Println("Serving on :8088")
357-
setupRoutes()
358-
}
359-
```
360-
361-
Then, to launch the script, open a terminal on the directory and use the following command:
362-
363-
```
364-
go run main.go
365-
```
366-
367-
Which, on success will return `Serving on :8088`.
368-
369-
**Step 2: OpenMV Script**
370-
371-
Next step is to launch the OpenMV editor. If you are not yet familiar with OpenMV, visit the [Getting Started with OpenMV]() section.
372-
373-
Once the editor is open, connect your board. Then, copy and paste the script below into the editor, and click on the green "PLAY" button.
374-
375-
***Please note that the `WIFI_SSID = "yournetwork"` and `WIFI_PASS = "yourpassword"` strings will need to be replaced with your credentials to your Wi-Fi network.***
376-
377-
```python
378-
import time
379-
import network
380-
import sensor
381-
import urequests
382-
import os
383-
384-
WIFI_SSID = "yournetwork"
385-
WIFI_PASS = "yourpassword"
386-
387-
url = 'http://10.130.22.213:8088/upload'
388-
389-
headers = {
390-
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:55.0) Gecko/20100101 Firefox/55.0',
391-
# Add more headers if needed
392-
}
393-
394-
class RAMBlockDev:
395-
def __init__(self, block_size, num_blocks):
396-
self.block_size = block_size
397-
self.data = bytearray(block_size * num_blocks)
398-
399-
def readblocks(self, block_num, buf, offset=0):
400-
addr = block_num * self.block_size + offset
401-
for i in range(len(buf)):
402-
buf[i] = self.data[addr + i]
403-
404-
def writeblocks(self, block_num, buf, offset=None):
405-
if offset is None:
406-
# do erase, then write
407-
for i in range(len(buf) // self.block_size):
408-
self.ioctl(6, block_num + i)
409-
offset = 0
410-
addr = block_num * self.block_size + offset
411-
for i in range(len(buf)):
412-
self.data[addr + i] = buf[i]
413-
414-
def ioctl(self, op, arg):
415-
if op == 4: # block count
416-
return len(self.data) // self.block_size
417-
if op == 5: # block size
418-
return self.block_size
419-
if op == 6: # block erase
420-
return 0
421-
422-
def sensor_init():
423-
sensor.reset()
424-
sensor.set_pixformat(sensor.RGB565)
425-
sensor.set_framesize(sensor.QVGA)
426-
sensor.skip_frames(time = 1000)
427-
428-
def wifi_connect():
429-
if not WIFI_SSID or not WIFI_PASS:
430-
raise (Exception("Network is not configured"))
431-
wlan = network.WLAN(network.STA_IF)
432-
wlan.active(True)
433-
wlan.connect(WIFI_SSID, WIFI_PASS)
434-
while not wlan.isconnected():
435-
#raise (Exception("Network is not configured, add SSID and pass to secrets.py"))
436-
time.sleep_ms(500)
437-
print("WiFi Connected ", wlan.ifconfig())
438-
439-
440-
441-
if __name__ == "__main__":
442-
sensor_init()
443-
wifi_connect()
444-
bdev = RAMBlockDev(512, 100)
445-
os.VfsFat.mkfs(bdev)
446-
os.mount(bdev, '/ramdisk')
447-
while (True):
448-
img = sensor.snapshot()
449-
jpg = img.compress()
450-
with open('/ramdisk/img.jpg', 'w') as f:
451-
f.write(jpg)
452-
f.close()
453-
files = {
454-
'image1': ('img.jpg', open('/ramdisk/img.jpg', 'rb'))
455-
}
456-
r = urequests.post(url, files=files, headers=headers)
457-
print(f"sending {jpg}")
458-
time.sleep(20.0)
459-
```
460-
461-
Once you run the script, the board will attempt to connect to the local Wi-Fi, and on success, it will capture an image and upload it.
462-
463-
This can now be accessed if your device is on the same local network.
464-
465-
### Motion Detection
290+
## Summary
466291
292+
In this article, we learned a bit more about the camera connector on board the GIGA R1 board, how it is connected to the STM32H747XI microcontroller, and a simple example on how to connect an inexpensive OV7675 camera module to a Processing application.

0 commit comments

Comments
 (0)