visit
#include <SparkFun_Ublox_Arduino_Library.h>
#include <Arduino_LSM9DS1.h>
#include <Arduino_APDS9960.h>
#include <SPI.h>
#include <SD.h>
// SD Vars
File dataFile;
int chipSelect = 4;
// GPS Vars
SFE_UBLOX_GPS myGPS; // Connected via UART
long latitude = 0;
long longitude = 0;
long speed = 0;
byte satellites = 0;
int timeout = 50;
long lastGPSTime = 0;
// IMU Vars
float ax, ay, az;
float gx, gy, gz;
// Misc
bool DEBUG = true;
int counter = 0;
#define LEDR (22u)
#define LEDG (23u)
#define LEDB (24u)
void setup()
{
// Setup User Terminal
Serial.begin(115200); // UART to PC/Mac
while(!Serial);
Serial1.begin(9600); // UART to GPS
while(!Serial1);
// Initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
pinMode(LEDR, OUTPUT);
pinMode(LEDB, OUTPUT);
pinMode(LEDG, OUTPUT);
digitalWrite(LEDR, HIGH); // LOW triggered LED....
digitalWrite(LEDG, HIGH);
digitalWrite(LEDB, HIGH);
// Setup GPS
if (!myGPS.begin(Serial1)) {
Serial.println(F("GPS not detected!"));
while (1);
}
Serial.println("GPS Started!");
// Setup SD Card
if (!SD.begin(chipSelect)) {
Serial.println("SD Card failed or not present!");
while (1);
}
// Remove Existing DATALOG.CSV file
if(SD.exists("DATALOG.CSV")) {
SD.remove("DATALOG.CSV");
dataFile = SD.open("DATALOG.CSV", FILE_WRITE);
dataFile.close();
}
delay(500); // Make sure existing DATALOG.CSV file is gone
// Create new CSV file with appropriate headers
dataFile = SD.open("DATALOG.CSV", FILE_WRITE);
dataFile.println("Count,AccX,AccY,AccZ,GyrX,GyrY,GyrZ,Lat,Long,Speed");
// Done with SD Card Init
Serial.println("SD Card Initialized!");
// Setup Gesture Sensor
if (!APDS.begin()) {
Serial.println("Error initializing gesture sensor!");
}
APDS.setGestureSensitivity(85);
Serial.println("Gesture sensor initialized!");
// Setup IMU
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
while(1);
}
Serial.println("IMU initialized!");
}
void loop()
{
if (millis() - lastGPSTime > 500) {
lastGPSTime = millis(); // Update the timer
latitude = myGPS.getLatitude(timeout);
longitude = myGPS.getLongitude(timeout);
speed = myGPS.getGroundSpeed(timeout);
satellites = myGPS.getSIV(timeout);
if(DEBUG) {
Serial.print(F("Lat: "));
Serial.print(latitude);
Serial.print(F(" Long: "));
Serial.print(longitude);
Serial.print(F(" (degrees * 10^-7)"));
Serial.print(F(" Speed: "));
Serial.print(speed);
Serial.print(F(" (mm/s)"));
Serial.print(F(" satellites: "));
Serial.println(satellites);
}
}
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(ax, ay, az);
if(DEBUG) {
Serial.print(F("Accel x: "));
Serial.print(ax);
Serial.print(F(" y: "));
Serial.print(ay);
Serial.print(F(" z: "));
Serial.println(az);
}
}
if (IMU.gyroscopeAvailable()) {
IMU.readGyroscope(gx, gy, gz);
if(DEBUG) {
Serial.print(F("Gyro x: "));
Serial.print(gx);
Serial.print(F(" y: "));
Serial.print(gy);
Serial.print(F(" z: "));
Serial.println(gz);
}
}
if (APDS.gestureAvailable()) {
// A gesture was detected, read and print to serial monitor
switch (APDS.readGesture()) {
case GESTURE_UP:
Serial.println("Detected UP gesture");
break;
case GESTURE_DOWN:
Serial.println("Detected DOWN gesture");
break;
case GESTURE_LEFT:
Serial.println("Detected LEFT gesture");
break;
case GESTURE_RIGHT:
Serial.println("Detected RIGHT gesture");
break;
default:
// ignore
break;
}
}
if (dataFile) {
counter += 1;
String dataString = "";
dataString += String(counter) + ",";
dataString += String(ax) + ",";
dataString += String(ay) + ",";
dataString += String(az) + ",";
dataString += String(gx) + ",";
dataString += String(gy) + ",";
dataString += String(gz) + ",";
dataString += String(latitude) + ",";
dataString += String(longitude) + ",";
dataString += String(speed);
dataFile.println(dataString);
}
delay(150); // Don't pound too hard
}
You can find the Arduino
bootloader.bin
binary file here:/Users/<username>/Library/Arduino15/packages/arduino/hardware/mbed/1.1.4/bootloaders/nano33ble/bootloader.bin
Turns out I had made a few mistakes in my reverse engineering, though.
The Nano 33 schematic has a Do Not Populate (DNP) for a pull up resistor on the RESET pin. I should have added test points for this resistor as well. I ended up hand-soldering a 4.7K. This stopped my board from auto-resetting every second (could also adjust the UICR to disable the RESET pin).The schematic shows a 1M Ohm resistor connecting the USB shield to ground. But the Eagle file shows 330 Ohm — should be 330 Ohms. There is tons of debate and trade-offs here.I messed up a wire with the gesture sensor, so that didn’t work. However it still measured RGB colors.I ended up fixing these issues. To make this device portable, I added a battery connection and LiPo charging, as well as load sharing. I also added a 5V and 3.3V power rail to power external devices.