Skip to content

Commit b2d9465

Browse files
authored
Merge pull request #1 from tinyMLx/addingLibraryFeatures
Adding library features and OV767X Library
2 parents e205139 + 99b9f47 commit b2d9465

File tree

17 files changed

+3767
-83
lines changed

17 files changed

+3767
-83
lines changed

Diff for: LICENSE.txt

+339
Large diffs are not rendered by default.

Diff for: README.md

+15-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,15 @@
1-
# arduino-library
1+
# Harvard_TinyMLx Arduino Library
2+
3+
Source code and examples for using and testing your Tiny Machine Learning Kit and Shield.
4+
5+
This library also includes a modified verison of the 0.0.2 version of the OV767X Library for Arduino (Copyright (c) 2020 Arduino SA) which is based on https://www.kernel.org[Linux Kernel's] V4L2 driver for OmniVision OV7670 cameras - which was created by Jonathan Corbet.
6+
7+
== License ==
8+
9+
Copyright (c) 2021 TinyMLx. All rights reserved.
10+
11+
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2.
12+
13+
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14+
15+
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

Diff for: examples/test_camera/test_camera.ino

+10-44
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,14 @@
33
Harvard University
44
tinyMLx - OV7675 Camera Test
55
6-
Requires the the Arduino_OV767X library
76
*/
87

9-
#include <Arduino_OV767X.h>
10-
11-
#define BUTTON_PIN 13
8+
#include <TinyMLShield.h>
129

1310
bool commandRecv = false; // flag used for indicating receipt of commands from serial port
1411
bool liveFlag = false; // flag as true to live stream raw camera bytes, set as false to take single images on command
1512
bool captureFlag = false;
1613

17-
// Variables for button debouncing
18-
unsigned long lastDebounceTime = 0;
19-
unsigned long debounceDelay = 50;
20-
bool lastButtonState = HIGH;
21-
bool buttonState;
22-
2314
// Image buffer;
2415
byte image[176 * 144 * 2]; // QCIF: 176x144 x 2 bytes per pixel (RGB565)
2516
int bytesPerFrame;
@@ -28,12 +19,10 @@ void setup() {
2819
Serial.begin(9600);
2920
while (!Serial);
3021

31-
pinMode(BUTTON_PIN, OUTPUT);
32-
digitalWrite(BUTTON_PIN, HIGH);
33-
nrf_gpio_cfg_out_with_input(digitalPinToPinName(BUTTON_PIN));
22+
initializeShield();
3423

35-
// Initialize camera
36-
if (!Camera.begin(QCIF, RGB565, 1)) {
24+
// Initialize the OV7675 camera
25+
if (!Camera.begin(QCIF, RGB565, 1, OV7675)) {
3726
Serial.println("Failed to initialize camera");
3827
while (1);
3928
}
@@ -50,28 +39,15 @@ void loop() {
5039
int i = 0;
5140
String command;
5241

53-
bool buttonRead = nrf_gpio_pin_read(digitalPinToPinName(BUTTON_PIN));
54-
55-
if (buttonRead != lastButtonState) {
56-
lastDebounceTime = millis();
57-
}
58-
59-
if (millis() - lastDebounceTime >= debounceDelay) {
60-
if (buttonRead != buttonState) {
61-
buttonState = buttonRead;
62-
63-
if (!buttonState) {
64-
if (!liveFlag) {
65-
if (!captureFlag) {
66-
captureFlag = true;
67-
}
68-
}
42+
bool clicked = readShieldButton();
43+
if (clicked) {
44+
if (!liveFlag) {
45+
if (!captureFlag) {
46+
captureFlag = true;
6947
}
7048
}
7149
}
7250

73-
lastButtonState = buttonRead;
74-
7551
// Read incoming commands from serial monitor
7652
while (Serial.available()) {
7753
char c = Serial.read();
@@ -132,14 +108,4 @@ void loop() {
132108
Serial.println();
133109
}
134110
}
135-
}
136-
137-
void nrf_gpio_cfg_out_with_input(uint32_t pin_number) {
138-
nrf_gpio_cfg(
139-
pin_number,
140-
NRF_GPIO_PIN_DIR_OUTPUT,
141-
NRF_GPIO_PIN_INPUT_CONNECT,
142-
NRF_GPIO_PIN_PULLUP,
143-
NRF_GPIO_PIN_S0S1,
144-
NRF_GPIO_PIN_NOSENSE);
145-
}
111+
}

Diff for: examples/test_microphone/test_microphone.ino

+27-38
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,21 @@
55
*/
66

77
#include <PDM.h>
8-
9-
#define BUTTON_PIN 13
8+
#include <TinyMLShield.h>
109

1110
// PDM buffer
1211
short sampleBuffer[256];
1312
volatile int samplesRead;
1413

15-
// Variables for button debouncing
16-
unsigned long lastDebounceTime = 0;
17-
unsigned long debounceDelay = 50;
18-
bool lastButtonState = HIGH;
19-
bool buttonState;
20-
2114
bool record = false;
15+
bool commandRecv = false;
2216

2317
void setup() {
2418
Serial.begin(9600);
2519
while (!Serial);
2620

27-
pinMode(BUTTON_PIN, OUTPUT);
28-
digitalWrite(BUTTON_PIN, HIGH);
29-
nrf_gpio_cfg_out_with_input(digitalPinToPinName(BUTTON_PIN));
21+
// Initialize the TinyML Shield
22+
initializeShield();
3023

3124
PDM.onReceive(onPDMdata);
3225
// Initialize PDM microphone in mono mode with 16 kHz sample rate
@@ -36,38 +29,44 @@ void setup() {
3629
}
3730

3831
Serial.println("Welcome to the microphone test for the built-in microphone on the Nano 33 BLE Sense\n");
39-
Serial.println("Use the on-shield button to start and stop an audio recording");
32+
Serial.println("Use the on-shield button or send the command 'click' to start and stop an audio recording");
4033
Serial.println("Open the Serial Plotter to view the corresponding waveform");
4134
}
4235

4336
void loop() {
44-
bool buttonRead = nrf_gpio_pin_read(digitalPinToPinName(BUTTON_PIN));
45-
46-
if (buttonRead != lastButtonState) {
47-
lastDebounceTime = millis();
37+
// see if the button is pressed and turn off or on recording accordingly
38+
bool clicked = readShieldButton();
39+
if (clicked){
40+
record = !record;
4841
}
49-
50-
if (millis() - lastDebounceTime >= debounceDelay) {
51-
if (buttonRead != buttonState) {
52-
buttonState = buttonRead;
53-
54-
if (!buttonState) {
55-
record = !record;
56-
}
42+
43+
// see if a command was sent over the serial monitor and record it if so
44+
String command;
45+
while (Serial.available()) {
46+
char c = Serial.read();
47+
if ((c != '\n') && (c != '\r')) {
48+
command.concat(c);
49+
}
50+
else if (c == '\r') {
51+
commandRecv = true;
52+
command.toLowerCase();
5753
}
5854
}
5955

60-
lastButtonState = buttonRead;
61-
62-
if (samplesRead) {
56+
// parse the command if applicable
57+
if (commandRecv && command == "click") {
58+
commandRecv = false;
59+
record = !record;
60+
}
6361

62+
// display the audio if applicable
63+
if (samplesRead) {
6464
// print samples to serial plotter
6565
if (record) {
6666
for (int i = 0; i < samplesRead; i++) {
6767
Serial.println(sampleBuffer[i]);
6868
}
6969
}
70-
7170
// clear read count
7271
samplesRead = 0;
7372
}
@@ -82,13 +81,3 @@ void onPDMdata() {
8281

8382
samplesRead = bytesAvailable / 2;
8483
}
85-
86-
void nrf_gpio_cfg_out_with_input(uint32_t pin_number) {
87-
nrf_gpio_cfg(
88-
pin_number,
89-
NRF_GPIO_PIN_DIR_OUTPUT,
90-
NRF_GPIO_PIN_INPUT_CONNECT,
91-
NRF_GPIO_PIN_PULLUP,
92-
NRF_GPIO_PIN_S0S1,
93-
NRF_GPIO_PIN_NOSENSE);
94-
}

Diff for: extras/CameraCapture/CameraCapture.ino

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
OV767X - Camera Test Pattern
3+
4+
This sketch waits for the letter 'c' on the Serial Monitor,
5+
it then reads a frame from the OmniVision OV7670 camera and
6+
prints the data to the Serial Monitor as a hex string.
7+
8+
The website https://rawpixels.net - can be used the visualize the data:
9+
width: 176
10+
height: 144
11+
RGB565
12+
Little Endian
13+
14+
Circuit:
15+
- Arduino Nano 33 BLE board
16+
- OV7670 camera module:
17+
- 3.3 connected to 3.3
18+
- GND connected GND
19+
- SIOC connected to A5
20+
- SIOD connected to A4
21+
- VSYNC connected to 8
22+
- HREF connected to A1
23+
- PCLK connected to A0
24+
- XCLK connected to 9
25+
- D7 connected to 4
26+
- D6 connected to 6
27+
- D5 connected to 5
28+
- D4 connected to 3
29+
- D3 connected to 2
30+
- D2 connected to 0 / RX
31+
- D1 connected to 1 / TX
32+
- D0 connected to 10
33+
34+
This example code is in the public domain.
35+
*/
36+
37+
#include <Arduino_OV767X.h>
38+
39+
unsigned short pixels[176 * 144]; // QCIF: 176x144 X 2 bytes per pixel (RGB565)
40+
41+
void setup() {
42+
Serial.begin(9600);
43+
while (!Serial);
44+
45+
Serial.println("OV767X Camera Capture");
46+
Serial.println();
47+
48+
if (!Camera.begin(QCIF, RGB565, 1, OV7675)) {
49+
Serial.println("Failed to initialize camera!");
50+
while (1);
51+
}
52+
53+
Serial.println("Camera settings:");
54+
Serial.print("\twidth = ");
55+
Serial.println(Camera.width());
56+
Serial.print("\theight = ");
57+
Serial.println(Camera.height());
58+
Serial.print("\tbits per pixel = ");
59+
Serial.println(Camera.bitsPerPixel());
60+
Serial.println();
61+
62+
Serial.println("Send the 'c' character to read a frame ...");
63+
Serial.println();
64+
}
65+
66+
void loop() {
67+
if (Serial.read() == 'c') {
68+
Serial.println("Reading frame");
69+
Serial.println();
70+
Camera.readFrame(pixels);
71+
72+
int numPixels = Camera.width() * Camera.height();
73+
74+
for (int i = 0; i < numPixels; i++) {
75+
unsigned short p = pixels[i];
76+
77+
if (p < 0x1000) {
78+
Serial.print('0');
79+
}
80+
81+
if (p < 0x0100) {
82+
Serial.print('0');
83+
}
84+
85+
if (p < 0x0010) {
86+
Serial.print('0');
87+
}
88+
89+
Serial.print(p, HEX);
90+
}
91+
}
92+
}
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
OV767X - Camera Capture Raw Bytes
3+
4+
This sketch reads a frame from the OmniVision OV7675 camera
5+
and writes the bytes to the Serial port. Use the Procesing
6+
sketch in the extras folder to visualize the camera output.
7+
8+
This example code is in the public domain.
9+
*/
10+
11+
#include <Arduino_OV767X.h>
12+
13+
int bytesPerFrame;
14+
15+
byte data[176 * 144 * 2]; // QVGA: 320x240 X 2 bytes per pixel (RGB565)
16+
17+
void setup() {
18+
Serial.begin(9600);
19+
while (!Serial);
20+
21+
if (!Camera.begin(QVGA, RGB565, 1, OV7675)) {
22+
Serial.println("Failed to initialize camera!");
23+
while (1);
24+
}
25+
26+
bytesPerFrame = Camera.width() * Camera.height() * Camera.bytesPerPixel();
27+
28+
// Optionally, enable the test pattern for testing
29+
// Camera.testPattern();
30+
}
31+
32+
void loop() {
33+
Camera.readFrame(data);
34+
35+
Serial.write(data, bytesPerFrame);
36+
}

0 commit comments

Comments
 (0)