Initial public release of WII5 Buoy firmware
Firmware for an autonomous wave-measurement buoy (ATmega2560-based WII5 v2 board). Reads wave motion from a Sparton AHRS-M1/M2 IMU, samples GPS and battery state, and reports back over Iridium SBD satellite telemetry. Originally developed 2012-2024. This is the first public release. Code, documentation, and field-tested operating modes (Capture, Sleep, Position, ManualTest, SelfTest, LowBattery) are licensed under Apache 2.0 — see LICENSE and NOTICE. See README.md for an overview and build instructions, CONTRIBUTING.md for how to contribute, and DEPLOYMENTS.md for the field-deployment log.
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright (c) 2012-2024 Scott Penrose <scottp@dd.com.au> and WII5 Buoy contributors
|
||||
//
|
||||
// This file is part of WII5 Buoy firmware.
|
||||
// See LICENSE for full terms.
|
||||
|
||||
/**
|
||||
* @file wii5_bindata.ino
|
||||
* @brief Test sketch: BinData layout/split exercise.
|
||||
*/
|
||||
|
||||
/*
|
||||
* BinData Test
|
||||
*/
|
||||
|
||||
#include <WII5Sh3dConsole.h>
|
||||
#include <WII5_board.h>
|
||||
#include <WII5Setup.h>
|
||||
#include <WII5.h>
|
||||
#include <WII5Data.h>
|
||||
|
||||
void setup() {
|
||||
wii5Setup.setupConsole();
|
||||
wii5Setup.setupIO();
|
||||
console.printf(F("waiting 1 seconds\r\n"));
|
||||
delay(1000);
|
||||
console.printf(F("WII5: Test BinData\r\n"));
|
||||
}
|
||||
|
||||
elapsedMillis wdtWait = 0;
|
||||
void loop() {
|
||||
if (wdtWait > 5100) {
|
||||
digitalWrite(WDT_RESET, LOW);
|
||||
wdtWait = 0;
|
||||
}
|
||||
else if (wdtWait > 5000) {
|
||||
digitalWrite(WDT_RESET, HIGH);
|
||||
}
|
||||
|
||||
sh3dNodeIO.loop();
|
||||
console.loop();
|
||||
if (console.available()) {
|
||||
switch(console.getCommand()) {
|
||||
case '0':
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
console.printf(F("BinData: showSizes\n"));
|
||||
wii5BinData.showSizes();
|
||||
|
||||
console.printf(F("BinData: Map Bits test\n"));
|
||||
for (uint8_t x = 0; x < 16; x++) {
|
||||
uint32_t t = 0;
|
||||
SetBit(t, x);
|
||||
|
||||
console.printf(F("X = %d, T = %lu\r\n"), x, t);
|
||||
|
||||
for (uint8_t y = 0; y < 16; y++) {
|
||||
if (BitVal(t, y)) {
|
||||
console.printf(F("BitVal matched on %d\r\n"), y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.printf(F("BinData: Trying first 32 types\r\n"));
|
||||
uint32_t binDataType = 0;
|
||||
while(1) {
|
||||
binDataType = (binDataType << 1) + 1;
|
||||
console.printf(F("BinData: type=%lu, size=%d\r\n"), binDataType, wii5BinData.getSize(binDataType));
|
||||
console.flush();
|
||||
delay(500);
|
||||
console.printf(F("BinData: Creating\r\n"));
|
||||
wii5BinData.setData(binDataType, wii5BinaryIridium, 340); // TODO Hard coded
|
||||
console.flush();
|
||||
delay(500);
|
||||
console.printf(F("BinData: type=%lu, size=%d\r\n"), binDataType, wii5BinData.getSize(binDataType));
|
||||
wii5BinData.dumpData(binDataType, wii5BinaryIridium, 340); // TODO Hard coded
|
||||
console.flush();
|
||||
delay(500);
|
||||
}
|
||||
|
||||
delay(5000);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright (c) 2012-2024 Scott Penrose <scottp@dd.com.au> and WII5 Buoy contributors
|
||||
//
|
||||
// This file is part of WII5 Buoy firmware.
|
||||
// See LICENSE for full terms.
|
||||
|
||||
/**
|
||||
* @file wii5_commands.ino
|
||||
* @brief Test sketch: command-protocol exercise.
|
||||
*/
|
||||
|
||||
#include "WII5.h"
|
||||
#include "WII5Commands.h"
|
||||
|
||||
void setup () {
|
||||
Serial.begin(115200);
|
||||
wii5Setup.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
wii5Commands.loop();
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright (c) 2012-2024 Scott Penrose <scottp@dd.com.au> and WII5 Buoy contributors
|
||||
//
|
||||
// This file is part of WII5 Buoy firmware.
|
||||
// See LICENSE for full terms.
|
||||
|
||||
/**
|
||||
* @file wii5_gps.ino
|
||||
* @brief Test sketch: GPS NMEA passthrough.
|
||||
*/
|
||||
|
||||
#include <WII5Sh3dConsole.h>
|
||||
#include <WII5.h>
|
||||
#include <WII5GPS.h>
|
||||
|
||||
#define SerialGPS Serial1
|
||||
|
||||
void setup() {
|
||||
// Serial
|
||||
Serial.begin(57600);
|
||||
console.begin();
|
||||
console.add(&Serial);
|
||||
console.printf(F("WII5: Test GPS"));
|
||||
|
||||
// GPS
|
||||
wii5Gps.begin();
|
||||
// wii5Gps.begin(&SerialGPS);
|
||||
// wii5Gps.setMode(WII5GPS_PASSTHROUGH);
|
||||
|
||||
wii5Gps.start();
|
||||
// wii5Gps.setMode(WII5GPS_PASSTHROUGH);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (SerialGPS.available()) {
|
||||
char c = SerialGPS.read();
|
||||
Serial.write(c);
|
||||
}
|
||||
return;
|
||||
|
||||
console.loop();
|
||||
wii5Gps.loop();
|
||||
if (console.available()) {
|
||||
console.printf(F("CONSOLE: Got command %c=%d \r\n"),
|
||||
console.getCommand(),
|
||||
console.getVal()
|
||||
);
|
||||
switch(console.getCommand()) {
|
||||
case '0':
|
||||
console.printf(F("setMode WII5GPS_OFF\n"));
|
||||
wii5Gps.setMode(WII5GPS_OFF);
|
||||
break;
|
||||
case '1':
|
||||
console.printf(F("setMode WII5GPS_QUIET\n"));
|
||||
wii5Gps.setMode(WII5GPS_QUIET);
|
||||
break;
|
||||
case '2':
|
||||
console.printf(F("setMode WII5GPS_PASSTHROUGH\n"));
|
||||
wii5Gps.setMode(WII5GPS_PASSTHROUGH);
|
||||
break;
|
||||
case '3':
|
||||
console.printf(F("setMode WII5GPS_TIMEONCE\n"));
|
||||
wii5Gps.setMode(WII5GPS_TIMEONCE);
|
||||
break;
|
||||
case '4':
|
||||
console.printf(F("setMode WII5GPS_POSONCE\n"));
|
||||
wii5Gps.setMode(WII5GPS_POSONCE);
|
||||
break;
|
||||
case '5':
|
||||
console.printf(F("setMode WII5GPS_POSACCURATE\n"));
|
||||
wii5Gps.setMode(WII5GPS_POSACCURATE);
|
||||
break;
|
||||
case '6':
|
||||
console.printf(F("setMode WII5GPS_POSREPEAT\n"));
|
||||
wii5Gps.setMode(WII5GPS_POSREPEAT);
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
// TODO dump;
|
||||
wii5Gps.dump();
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
// Status
|
||||
// - Number of bytes received
|
||||
// - Lock status etc
|
||||
break;
|
||||
|
||||
default:
|
||||
console.printf(F("GPS Help:\r\n"));
|
||||
console.printf(F(" 0 - mode off\r\n"));
|
||||
console.printf(F(" 1 - mode Quiet\r\n"));
|
||||
console.printf(F(" 2 - mode Passthrough\r\n"));
|
||||
console.printf(F(" 3 - mode Time Once\r\n"));
|
||||
console.printf(F(" 4 - mode Position Once\r\n"));
|
||||
console.printf(F(" 5 - mode Position Accurate\r\n"));
|
||||
console.printf(F(" 6 - mode Position Repeat\r\n"));
|
||||
console.printf(F(" D - Dump all data\r\n"));
|
||||
console.printf(F(" S - Show status\r\n"));
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright (c) 2012-2024 Scott Penrose <scottp@dd.com.au> and WII5 Buoy contributors
|
||||
//
|
||||
// This file is part of WII5 Buoy firmware.
|
||||
// See LICENSE for full terms.
|
||||
|
||||
/**
|
||||
* @file wii5_iridium.ino
|
||||
* @brief Test sketch: Iridium AT-command exercise.
|
||||
*/
|
||||
|
||||
#include <WII5Sh3dConsole.h>
|
||||
#include <WII5.h>
|
||||
#include <WII5Iridium.h>
|
||||
|
||||
void setup() {
|
||||
wii5Setup.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
wii5Iridium.loop();
|
||||
|
||||
console.loop();
|
||||
if (console.available()) {
|
||||
switch(console.getCommand()) {
|
||||
case 'p':
|
||||
console.log(LOG_DEBUG, F("IRIDIUM: 'p' passthrough toggle"));
|
||||
wii5Iridium.setPassthrough(!wii5Iridium.getPassthrough());
|
||||
console.log(LOG_DEBUG, F("IRIDIUM: passthrough=%d"), int(wii5Iridium.getPassthrough()));
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
console.log(LOG_DEBUG, F("IRIDIUM: 'd' debug toggle"));
|
||||
wii5Iridium.setDebug(!wii5Iridium.getDebug());
|
||||
console.log(LOG_DEBUG, F("IRIDIUM: debug=%d"), int(wii5Iridium.getDebug()));
|
||||
break;
|
||||
|
||||
case 's':
|
||||
console.log(LOG_DEBUG, F("IRIDIUM: 's' start"));
|
||||
wii5Iridium.start();
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
console.log(LOG_DEBUG, F("IRIDIUM: 'S' stop"));
|
||||
wii5Iridium.stop();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
};
|
||||
console.log(LOG_DEBUG, F("IRIDIUM: Status = %d"), wii5Iridium.getPassthrough());
|
||||
wii5Iridium.displayStatus();
|
||||
wii5Iridium.displayError();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright (c) 2012-2024 Scott Penrose <scottp@dd.com.au> and WII5 Buoy contributors
|
||||
//
|
||||
// This file is part of WII5 Buoy firmware.
|
||||
// See LICENSE for full terms.
|
||||
|
||||
/**
|
||||
* @file wii5_pins.ino
|
||||
* @brief Test sketch: multi-port serial passthrough for pin diagnostics.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
WII5 Pins
|
||||
|
||||
*/
|
||||
#include <elapsedMillis.h>
|
||||
#include <WII5Sh3dConsole.h>
|
||||
#include <Sh3dNodeUtil.h>
|
||||
|
||||
// TODO This needs serious normalisation for each serial port ! (A class perhaps)
|
||||
// Large Line buffers for passthrough
|
||||
#define BUFFER_SIZE 250
|
||||
#define DEVICE_MAX 6
|
||||
Stream *streams[DEVICE_MAX];
|
||||
char bufferSerial[DEVICE_MAX][BUFFER_SIZE + 1];
|
||||
uint8_t bufferPos[DEVICE_MAX];
|
||||
uint32_t count = 0;
|
||||
elapsedMillis passthroughWait = 0;
|
||||
bool passthroughSerial[DEVICE_MAX];
|
||||
|
||||
void setup() {
|
||||
// Short delay for debug / errors
|
||||
|
||||
Serial.begin(57600);
|
||||
console.begin();
|
||||
console.add(&Serial);
|
||||
|
||||
sh3dNodeUtil.begin();
|
||||
|
||||
// Start each port at the right speed
|
||||
Serial1.begin(9600);
|
||||
streams[1] = &Serial1;
|
||||
Serial2.begin(9600);
|
||||
streams[2] = &Serial2;
|
||||
Serial3.begin(9600);
|
||||
streams[3] = &Serial3;
|
||||
// Serial4.begin(9600);
|
||||
// streams[4] = &Serial4;
|
||||
// Serial5.begin(9600);
|
||||
// streams[5] = &Serial5;
|
||||
}
|
||||
|
||||
void processSerial(uint8_t id) {
|
||||
if (!streams[id]) {
|
||||
return;
|
||||
}
|
||||
while (streams[id]->available()) {
|
||||
char c = streams[id]->read();
|
||||
|
||||
// Ignore start/stop character of Wind Sonic
|
||||
if (c == 2)
|
||||
c = 'W';
|
||||
if (c == 3)
|
||||
c = '*';
|
||||
|
||||
if ( (c != '\n') && (c != '\r') ) {
|
||||
if (bufferPos[id] < BUFFER_SIZE) {
|
||||
bufferSerial[id][bufferPos[id]] = c;
|
||||
bufferPos[id]++;
|
||||
bufferSerial[id][bufferPos[id]] = '\0';
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (passthroughSerial[id]) {
|
||||
console.printf(F("S%d: (%lu) %s\r\n"), id, millis(), bufferSerial[id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elapsedMillis wait = 0;
|
||||
void loop() {
|
||||
// TODO Should not be hard coded 60 seconds
|
||||
/*
|
||||
if (passthroughWait > 60000) {
|
||||
// Skips 0
|
||||
for (uint8_t id = 1; id < DEVICE_MAX; id++) {
|
||||
passthroughSerial[id] = false;
|
||||
}
|
||||
console.log(LOG_INFO, F("Passthrough time expired"));
|
||||
}
|
||||
*/
|
||||
|
||||
console.loop();
|
||||
if (console.available()) {
|
||||
console.log(LOG_INFO, F("WII5 Console command received - %c=%d"),
|
||||
console.getCommand(),
|
||||
console.getVal()
|
||||
);
|
||||
|
||||
switch(console.getCommand()) {
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
// Toggle
|
||||
passthroughSerial[(uint8_t)console.getCommand() - '0']
|
||||
= !passthroughSerial[(uint8_t)console.getCommand() - '0'];
|
||||
// Reset timer - all off when hits time
|
||||
passthroughWait = 0;
|
||||
console.log(LOG_INFO,
|
||||
F("Passthrough enabled for $d for %d seconds"),
|
||||
(uint16_t)console.getCommand() - '0',
|
||||
60
|
||||
);
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
for (uint8_t id = 1; id < DEVICE_MAX; id++) {
|
||||
passthroughSerial[id] = true;
|
||||
}
|
||||
passthroughWait = 0;
|
||||
break;
|
||||
|
||||
// Output
|
||||
case 'o':
|
||||
console.printf(F("OUTPU pin=%d\r\n"), int(console.getVal()));
|
||||
pinMode(int(console.getVal()), OUTPUT);
|
||||
break;
|
||||
|
||||
// Output
|
||||
case 'i':
|
||||
console.printf(F("INPUT pin=%d\r\n"), int(console.getVal()));
|
||||
pinMode(int(console.getVal()), INPUT);
|
||||
break;
|
||||
|
||||
// Low
|
||||
case 'x':
|
||||
console.printf(F("LOW pin=%d\r\n"), int(console.getVal()));
|
||||
digitalWrite(int(console.getVal()), LOW);
|
||||
console.printf(F("pin=%d\r\n"), int(digitalRead(console.getVal())));
|
||||
break;
|
||||
|
||||
// HIGH
|
||||
case 'X':
|
||||
console.printf(F("HIGH pin=%d\r\n"), int(console.getVal()));
|
||||
digitalWrite(int(console.getVal()), HIGH);
|
||||
console.printf(F("pin=%d\r\n"), int(digitalRead(console.getVal())));
|
||||
break;
|
||||
|
||||
// Low
|
||||
case 's':
|
||||
console.printf(F("pin=%d, state=%d\r\n"), int(console.getVal()), int(digitalRead(console.getVal())));
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
// dumpPins();
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
case 'H':
|
||||
console.log(LOG_INFO, F(" WII5: Pins"));
|
||||
console.log(LOG_INFO, F(" 'L' - Stop logging"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (wait > 500) {
|
||||
console.printf(F("pin=%d, state=%d\r\n"), int(console.getVal()), int(digitalRead(console.getVal())));
|
||||
wait = 0;
|
||||
}
|
||||
|
||||
// Process all incoming Serial
|
||||
for (uint8_t id = 1; id < DEVICE_MAX; id++) {
|
||||
processSerial(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright (c) 2012-2024 Scott Penrose <scottp@dd.com.au> and WII5 Buoy contributors
|
||||
//
|
||||
// This file is part of WII5 Buoy firmware.
|
||||
// See LICENSE for full terms.
|
||||
|
||||
/**
|
||||
* @file wii5_sparton.ino
|
||||
* @brief Test sketch: Sparton AHRS exercise.
|
||||
*/
|
||||
|
||||
#include <WII5Sh3dConsole.h>
|
||||
#include <WII5.h>
|
||||
#include <WII5Sparton.h>
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
console.begin(WII5_BUFFER_CONSOLE_PRINT, WII5_BUFFER_CONSOLE_CMD);
|
||||
console.add(&Serial);
|
||||
console.printf(F("WII5: Test Sparton"));
|
||||
|
||||
wii5Sparton.begin();
|
||||
wii5Sparton.setDebug(true);
|
||||
|
||||
wii5Sparton.setRecords(5000);
|
||||
wii5Sparton.start();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
wii5Sparton.loop();
|
||||
console.loop();
|
||||
if (console.available()) {
|
||||
uint32_t val = console.getVal();
|
||||
console.printf(F("CONSOLE: Got command %c=%d \r\n"),
|
||||
console.getCommand(),
|
||||
val
|
||||
);
|
||||
switch(console.getCommand()) {
|
||||
// Toggle Sparton passthrough
|
||||
case 'p':
|
||||
console.log(LOG_DEBUG, F("SPARTON: 'p' passthrough toggle"));
|
||||
wii5Sparton.setPassthrough(!wii5Sparton.getPassthrough());
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (val < 100) val = 100;
|
||||
console.log(LOG_DEBUG, F("SPARTON: 's' start with %lu records"), val);
|
||||
wii5Sparton.setRecords(val);
|
||||
wii5Sparton.start();
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
console.log(LOG_DEBUG, F("SPARTON: 'S' stop"));
|
||||
wii5Sparton.stop();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
};
|
||||
console.log(LOG_DEBUG, F("SPARTON: Status = %d"), wii5Sparton.getPassthrough());
|
||||
wii5Sparton.displayStatus();
|
||||
wii5Sparton.displayError();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright (c) 2012-2024 Scott Penrose <scottp@dd.com.au> and WII5 Buoy contributors
|
||||
//
|
||||
// This file is part of WII5 Buoy firmware.
|
||||
// See LICENSE for full terms.
|
||||
|
||||
/**
|
||||
* @file wii5_weather_18b20.ino
|
||||
* @brief Test sketch: DS18B20 temperature exercise.
|
||||
*/
|
||||
|
||||
#include "WII5.h"
|
||||
#include "WII5Weather_18B20.h"
|
||||
|
||||
void setup () {
|
||||
Serial.begin(115200);
|
||||
console.begin();
|
||||
console.add(&Serial);
|
||||
wii5Weather_18B20.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
wii5Weather_18B20.temperatureRead();
|
||||
delay(5000);
|
||||
}
|
||||
Reference in New Issue
Block a user