Skip to content

Commit 198abb7

Browse files
committed
Add an example that moves an image
1 parent 0151fbf commit 198abb7

File tree

1 file changed

+197
-0
lines changed

1 file changed

+197
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
// Remote Control - As The Controller Device
2+
//
3+
// This script configures your Arduino to remotely control an OpenMV Cam using the RPC
4+
// library.
5+
//
6+
// This script is designed to pair with "image_transfer_jpg_as_the_remote_device.py" running
7+
// on the OpenMV Cam. The script is in OpenMV IDE under Files -> Examples -> Remote Control.
8+
9+
#include <SPI.h>
10+
#include <SD.h>
11+
#include <openmvrpc.h>
12+
13+
const int SD_CARD_CHIP_SELECT_PIN = 4;
14+
15+
// The RPC library above provides mutliple classes for controlling an OpenMV Cam over
16+
// CAN, I2C, SPI, or Serial (UART).
17+
18+
// We need to define a scratch buffer for holding messages. The maximum amount of data
19+
// you may pass in any on direction is limited to the size of this buffer.
20+
21+
openmv::rpc_scratch_buffer<256> scratch_buffer; // All RPC objects share this buffer.
22+
23+
///////////////////////////////////////////////////////////////
24+
// Choose the interface you wish to control an OpenMV Cam over.
25+
///////////////////////////////////////////////////////////////
26+
27+
// Uncomment the below line to setup your Arduino for controlling over CAN.
28+
//
29+
// * message_id - CAN message to use for data transport on the can bus (11-bit).
30+
// * bit_rate - CAN bit rate.
31+
//
32+
// NOTE: Master and slave message ids and can bit rates must match. Connect master can high to slave
33+
// can high and master can low to slave can lo. The can bus must be terminated with 120 ohms.
34+
//
35+
// openmv::rpc_can_master interface(0x7FF, 250E3);
36+
37+
// Uncomment the below line to setup your Arduino for controlling over I2C.
38+
//
39+
// * slave_addr - I2C address.
40+
// * rate - I2C Bus Clock Frequency.
41+
//
42+
// NOTE: Master and slave addresses must match. Connect master scl to slave scl and master sda
43+
// to slave sda. You must use external pull ups. Finally, both devices must share a ground.
44+
//
45+
// openmv::rpc_i2c_master interface(0x12, 100000);
46+
47+
// Uncomment the below line to setup your Arduino for controlling over SPI.
48+
//
49+
// * cs_pin - Slave Select Pin.
50+
// * freq - SPI Bus Clock Frequency.
51+
// * spi_mode - See (https://www.arduino.cc/en/reference/SPI)
52+
//
53+
// NOTE: Master and slave settings much match. Connect CS, SCLK, MOSI, MISO to CS, SCLK, MOSI, MISO.
54+
// Finally, both devices must share a common ground.
55+
//
56+
// openmv::rpc_spi_master interface(10, 1000000, SPI_MODE2);
57+
58+
// Uncomment the below line to setup your Arduino for controlling over a hardware UART.
59+
//
60+
// * baudrate - Serial Baudrate.
61+
//
62+
// NOTE: Master and slave baud rates must match. Connect master tx to slave rx and master rx to
63+
// slave tx. Finally, both devices must share a common ground.
64+
//
65+
// WARNING: The program and debug port for your Arduino may be "Serial". If so, you cannot use
66+
// "Serial" to connect to an OpenMV Cam without blocking your Arduino's ability to
67+
// be programmed and use print/println.
68+
//
69+
// openmv::rpc_hardware_serial_uart_master -> Serial
70+
// openmv::rpc_hardware_serial1_uart_master -> Serial1
71+
// openmv::rpc_hardware_serial2_uart_master -> Serial2
72+
// openmv::rpc_hardware_serial3_uart_master -> Serial3
73+
//
74+
// openmv::rpc_hardware_serial1_uart_master interface(115200);
75+
76+
// Uncomment the below line to setup your Arduino for controlling over a software UART.
77+
//
78+
// * rx_pin - RX Pin (See the reference guide about what pins can be used)
79+
// * tx_pin - TX Pin (see the reference guide about what pins can be used)
80+
// * baudrate - Serial Baudrate (See the reference guide https://www.arduino.cc/en/Reference/SoftwareSerial)
81+
//
82+
// NOTE: Master and slave baud rates must match. Connect master tx to slave rx and master rx to
83+
// slave tx. Finally, both devices must share a common ground.
84+
//
85+
openmv::rpc_software_serial_uart_master interface(2, 3, 19200);
86+
87+
void setup() {
88+
89+
// For MCP2515 CAN we might need to change the default CAN settings for the Arduino Uno.
90+
//
91+
// CAN.setPins(9, 2); // CS & INT
92+
// CAN.setClockFrequency(16E6); // 16 MHz
93+
94+
// Startup the RPC interface and a debug channel.
95+
interface.begin();
96+
Serial.begin(115200);
97+
98+
// Initialize the SD Card
99+
100+
while (!Serial); // wait for Serial Monitor to connect. Needed for native USB port boards only:
101+
102+
Serial.println(F("Initializing SD card..."));
103+
104+
if (!SD.begin(SD_CARD_CHIP_SELECT_PIN)) {
105+
Serial.println(F("initialization failed. Things to check:"));
106+
Serial.println(F("1. is a card inserted?"));
107+
Serial.println(F("2. is your wiring correct?"));
108+
Serial.println(F("3. did you change the chipSelect pin to match your shield or module?"));
109+
Serial.println(F("Note: press reset or reopen this serial monitor after fixing your issue!"));
110+
while (true);
111+
}
112+
113+
Serial.println(F("Initialization done."));
114+
}
115+
116+
void loop() {
117+
// The script running on the OpenMV Cam will evaluate the string below to set the pixformat and framesize.
118+
const char pixformat_and_framesize[] = "Sensor.RGB565,Sensor.QVGA";
119+
uint32_t jpeg_size;
120+
121+
// jpeg_image_snapshot will take a jpeg picture, store it in memory on the OpenMV Cam, and then return the
122+
// jpg image size in bytes for reading by the Arduino.
123+
Serial.println(F("Taking a pic..."));
124+
if (interface.call(F("jpeg_image_snapshot"),
125+
pixformat_and_framesize, sizeof(pixformat_and_framesize),
126+
&jpeg_size, sizeof(jpeg_size))) {
127+
Serial.println(F("Success"));
128+
129+
// We need to generate a filename now to save the jpg image data too. The below code reformats the
130+
// 5-digit file name string based on a counter that will increment each time we save an image.
131+
static uint16_t file_counter = 0;
132+
char filename[] = "00000.JPG";
133+
filename[0] = ((file_counter / 10000) % 10);
134+
filename[1] = ((file_counter / 1000) % 10);
135+
filename[2] = ((file_counter / 100) % 10);
136+
filename[3] = ((file_counter / 10) % 10);
137+
filename[4] = ((file_counter / 1) % 10);
138+
139+
// Try to create the filename. If a file already exists with the same name it will be deleted.
140+
Serial.println(F("Creating jpg file..."));
141+
SD.remove(filename);
142+
File jpg_file = SD.open(filename, FILE_WRITE);
143+
144+
if (jpg_file) {
145+
// jpeg_image_read takes two arguments, offset and size.
146+
// We can easily pass the two arguments as a struct.
147+
struct {
148+
uint32_t offset;
149+
uint32_t size;
150+
} arg;
151+
152+
// To read the file we have to read a chunk at a time which is limited to our max buffer size.
153+
arg.offset = 0;
154+
arg.size = scratch_buffer.buffer_size();
155+
156+
// Now read one chunk of the file after another in order.
157+
while (true) {
158+
// interface.call_no_copy() will return a pointer to data inside the scratch buffer that has
159+
// been transferred. This saves us from needing another data buffer in RAM.
160+
char *jpg_data;
161+
size_t jpg_data_len;
162+
163+
// Transfer the bytes. jpg_data and jpg_data_len on success will point to the data transferred.
164+
Serial.println(F("Reading bytes..."));
165+
if (interface.call_no_copy(F("jpeg_image_read"), &arg, sizeof(arg), &jpg_data, &jpg_data_len)) {
166+
Serial.println(F("Writing bytes..."));
167+
168+
// Finally, write the bytes to the SD card.
169+
if (jpg_file.write(jpg_data, jpg_data_len) == jpg_data_len) {
170+
// Once the data has been written increment our offset in the jpeg file we are reading.
171+
arg.offset += jpg_data_len;
172+
173+
// Close the file and go to the next one once finished.
174+
if (arg.offset >= jpeg_size) {
175+
Serial.println(F("File Saved"));
176+
jpg_file.close();
177+
file_counter += 1;
178+
break;
179+
}
180+
} else {
181+
Serial.println(F("Failed!"));
182+
jpg_file.close();
183+
break;
184+
}
185+
} else {
186+
Serial.println(F("Failed!"));
187+
jpg_file.close();
188+
break;
189+
}
190+
}
191+
} else {
192+
Serial.println(F("Failed!"));
193+
}
194+
} else {
195+
Serial.println(F("Failed!"));
196+
}
197+
}

0 commit comments

Comments
 (0)