-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathGIGA-R1.ino
124 lines (109 loc) · 4.66 KB
/
GIGA-R1.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// 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, either version 3 of the License, or
// (at your option) any later version.
//
// 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.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// Copyright (c) 2024 Upside Down Labs - [email protected]
// Author: Deepak Khatri
//
// At Upside Down Labs, we create open-source DIY neuroscience hardware and software.
// Our mission is to make neuroscience affordable and accessible for everyone.
// By supporting us with your purchase, you help spread innovation and open science.
// Thank you for being part of this journey with us!
#include <Arduino.h>
#include <Arduino_AdvancedAnalog.h>
// Definitions
#define NUM_CHANNELS 6 // Number of channels supported
#define HEADER_LEN 4 // Header = SYNC_BYTE_1 + SYNC_BYTE_2 + Counter +
#define PACKET_LEN (NUM_CHANNELS * 2 + HEADER_LEN) // Packet length = Header + Data + END_BYTE
#define ADC_SAMPLING 16000 // ADC sampling rate
#define ADC_QUEUE 256 // ADC Qeueue depth
#define ADC_RES 16 // ADC Resolutiton
#define SAMPLES_CHANNEL 32 // Samples per channel
#define SAMP_RATE ADC_SAMPLING / SAMPLES_CHANNEL // CHORDS Sampling rate (250/500 for GIGA R1 WiFi)
#define SYNC_BYTE_1 0xC7 // Packet first byte
#define SYNC_BYTE_2 0x7C // Packet second byte
#define BAUD_RATE 230400 // Serial connection baud rate
// Global constants and variables
uint8_t packetBuffer[PACKET_LEN]; // The transmission packet
uint8_t currentChannel; // Current channel being sampled
bool adcStatus = false; // Timer status bit
uint16_t adcValue = 0; // ADC current value
// Channel to use from A0 - A11
AdvancedADC adc(A0, A1, A2, A3, A4, A5);
void adcStart() {
adcStatus = true;
digitalWrite(LED_BUILTIN, LOW);
// Resolution, sample rate, number of samples per channel, queue depth.
if (!adc.begin(AN_RESOLUTION_16, ADC_SAMPLING, SAMPLES_CHANNEL, ADC_QUEUE, true)) {
Serial.println("Failed to start analog acquisition!");
while (1)
;
}
}
void adcStop() {
adcStatus = false;
digitalWrite(LED_BUILTIN, HIGH);
adc.stop();
}
void setup() {
Serial.begin(BAUD_RATE);
while (!Serial) {
; // Wait for serial port to connect. Needed for native USB
}
// Status LED
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
// Initialize packetBuffer
packetBuffer[0] = SYNC_BYTE_1; // Sync 0
packetBuffer[1] = SYNC_BYTE_2; // Sync 1
packetBuffer[2] = 0; // Packet counter
packetBuffer[3] = ((NUM_CHANNELS << 4) - 1)
| (ADC_RES - 10); // Config Byte
}
void loop() {
// Send data if the buffer is ready and the timer is activ
if (adcStatus and adc.available()) {
SampleBuffer adcBuffer = adc.read();
// Read 6ch ADC inputs and store current values in packetBuffer
for (currentChannel = 0; currentChannel < NUM_CHANNELS; currentChannel++) {
adcValue = adcBuffer[currentChannel]; // Read Analog input
packetBuffer[((2 * currentChannel) + HEADER_LEN)] = highByte(adcValue); // Write High Byte
packetBuffer[((2 * currentChannel) + HEADER_LEN + 1)] = lowByte(adcValue); // Write Low Byte
}
// Increment the packet counter
packetBuffer[2]++;
// Release the buffer to return it to the pool.
adcBuffer.release();
// Write packetBuffer to Serial
Serial.write(packetBuffer, PACKET_LEN);
}
if (Serial.available()) {
String command = Serial.readStringUntil('\n');
command.trim(); // Remove extra spaces or newline characters
command.toUpperCase(); // Normalize to uppercase for case-insensitivity
if (command == "WHORU") // Who are you?
{
Serial.println("GIGA-R1");
} else if (command == "START") // Start data acquisition
{
adcStart();
} else if (command == "STOP") // Stop data acquisition
{
adcStop();
} else if (command == "STATUS") // Get status
{
Serial.println(adcStatus ? "RUNNING" : "STOPPED");
} else {
Serial.println("UNKNOWN COMMAND");
}
}
}