Attempt at building a platformio version before starting on changes to testing
This commit is contained in:
@@ -41,7 +41,33 @@ External vendor documentation is not redistributed in this repo; see
|
|||||||
|
|
||||||
## Build & flash
|
## Build & flash
|
||||||
|
|
||||||
This is an Arduino-IDE / `arduino-cli` project, not PlatformIO.
|
This builds with either **PlatformIO** or the original **Arduino-IDE /
|
||||||
|
`arduino-cli`** toolchain — the sources stay at the repo root and both flows
|
||||||
|
compile them in place.
|
||||||
|
|
||||||
|
### PlatformIO (recommended)
|
||||||
|
|
||||||
|
`platformio.ini` lives at the repo root and defines a single `wii5_buoy`
|
||||||
|
environment with a custom board (`boards/wii5_v2_2560.json`: ATmega2560 @
|
||||||
|
11.0592 MHz, serial bootloader @ 230400).
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pio run # compile (env: wii5_buoy)
|
||||||
|
pio run -t upload # compile + flash (override port with --upload-port)
|
||||||
|
pio device monitor # serial console @ 230400
|
||||||
|
```
|
||||||
|
|
||||||
|
Public library dependencies are declared in `lib_deps` and fetched
|
||||||
|
automatically. Scott's own libraries (`AvgStd`, `PushButton`, `MemoryFree`,
|
||||||
|
`SDBlock`) are vendored under `lib/`. The entry sketch
|
||||||
|
`app/wii5_buoy/wii5_buoy.ino` is pulled into the build by `pio_main.cpp`
|
||||||
|
(PlatformIO only auto-detects sketches at the source-dir root).
|
||||||
|
|
||||||
|
> Note: PlatformIO's registry library versions differ from the historical
|
||||||
|
> arduino-cli set, so the flash footprint is larger than the figures quoted
|
||||||
|
> elsewhere in this repo. Pin specific `lib_deps` versions if you need parity.
|
||||||
|
|
||||||
|
### Arduino IDE / arduino-cli
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# Verify the sketch compiles
|
# Verify the sketch compiles
|
||||||
@@ -112,6 +138,10 @@ A running log of notable real-world deployments lives in `DEPLOYMENTS.md`.
|
|||||||
app/wii5_buoy/ Arduino sketch entry point
|
app/wii5_buoy/ Arduino sketch entry point
|
||||||
WII5*.{h,cpp} Firmware source (board root, see Architecture)
|
WII5*.{h,cpp} Firmware source (board root, see Architecture)
|
||||||
WII5_board_v2.h Pin/peripheral map for the WII5 v2 board
|
WII5_board_v2.h Pin/peripheral map for the WII5 v2 board
|
||||||
|
platformio.ini PlatformIO build configuration
|
||||||
|
boards/ PlatformIO custom board definition (wii5_v2_2560.json)
|
||||||
|
pio_main.cpp PlatformIO entry shim (#includes the .ino sketch)
|
||||||
|
lib/ Vendored libraries (AvgStd, PushButton, MemoryFree, SDBlock)
|
||||||
doc/ Design notes, command reference, generated API docs
|
doc/ Design notes, command reference, generated API docs
|
||||||
test/ Smaller per-subsystem test sketches
|
test/ Smaller per-subsystem test sketches
|
||||||
tools/ Build, flash, and size-profile helper scripts
|
tools/ Build, flash, and size-profile helper scripts
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"build": {
|
||||||
|
"core": "arduino",
|
||||||
|
"extra_flags": "-DARDUINO_AVR_MEGA2560",
|
||||||
|
"f_cpu": "11059200L",
|
||||||
|
"mcu": "atmega2560",
|
||||||
|
"variant": "mega"
|
||||||
|
},
|
||||||
|
"frameworks": ["arduino"],
|
||||||
|
"name": "WII5 v2 (ATmega2560 3V3 11.0592MHz)",
|
||||||
|
"url": "https://github.com/scottpenrose/WII5Firmware",
|
||||||
|
"upload": {
|
||||||
|
"maximum_ram_size": 8192,
|
||||||
|
"maximum_size": 258048,
|
||||||
|
"protocol": "arduino",
|
||||||
|
"speed": 230400
|
||||||
|
},
|
||||||
|
"vendor": "WII"
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
/**
|
||||||
|
* Library to calculate the average and standard deviation of a
|
||||||
|
* reading iteratively: without storing the whole data set.
|
||||||
|
*
|
||||||
|
* Stores:
|
||||||
|
* double average
|
||||||
|
* double variance
|
||||||
|
* int numberOfReadings
|
||||||
|
* double min
|
||||||
|
* double max
|
||||||
|
**/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (c) 2016 Edoardo Pasca
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AvgStd.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
|
AvgStd::AvgStd(){
|
||||||
|
AvgStd::reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AvgStd::checkAndAddReading(float val){
|
||||||
|
|
||||||
|
if (N < 10)
|
||||||
|
AvgStd::addReading(val);
|
||||||
|
else {
|
||||||
|
if (r_sigma == -1)
|
||||||
|
AvgStd::addReading(val);
|
||||||
|
else {
|
||||||
|
if (abs(avg - val) <= (r_sigma * sqrt(var)) )
|
||||||
|
AvgStd::addReading(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void AvgStd::addReading(float val){
|
||||||
|
|
||||||
|
if (N == 0) {
|
||||||
|
avg = val;
|
||||||
|
min = val;
|
||||||
|
max = val;
|
||||||
|
} else if (N == 1) {
|
||||||
|
//set min/max
|
||||||
|
max = val > max? val : max;
|
||||||
|
min = val < min? val : min;
|
||||||
|
|
||||||
|
|
||||||
|
float thisavg = (avg + val)/2;
|
||||||
|
// initial value is in avg
|
||||||
|
var = (avg - thisavg)*(avg-thisavg) + (val - thisavg) * (val-thisavg);
|
||||||
|
avg = thisavg;
|
||||||
|
} else {
|
||||||
|
// set min/max
|
||||||
|
max = val > max? val : max;
|
||||||
|
min = val < min? val : min;
|
||||||
|
|
||||||
|
float M = (float)N;
|
||||||
|
|
||||||
|
var = var * ((M-1)/M) + ((val - avg)*(val - avg)/(M+1)) ;
|
||||||
|
|
||||||
|
avg = avg * (M/(M+1)) + val / (M+1);
|
||||||
|
}
|
||||||
|
N++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AvgStd::reset(){
|
||||||
|
N = 0;
|
||||||
|
avg = 0;
|
||||||
|
var = 0;
|
||||||
|
min = 0;
|
||||||
|
max = 0;
|
||||||
|
r_sigma = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
float AvgStd::getMean(){return avg;}
|
||||||
|
float AvgStd::getStd() {
|
||||||
|
float ret = -1;
|
||||||
|
if (N>1)
|
||||||
|
ret = sqrt(var);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
float AvgStd::getVariance() {return var;}
|
||||||
|
unsigned int AvgStd::getN(){return N;}
|
||||||
|
float AvgStd::getMin() {return min;}
|
||||||
|
float AvgStd::getMax() {return max;}
|
||||||
|
|
||||||
|
void AvgStd::setRejectionSigma(float sigmas){
|
||||||
|
r_sigma = sigmas;
|
||||||
|
};
|
||||||
|
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
* Library to calculate the average and standard deviation of a
|
||||||
|
* reading iteratively: without storing the whole data set.
|
||||||
|
*
|
||||||
|
* Stores:
|
||||||
|
* double average
|
||||||
|
* double variance
|
||||||
|
* int numberOfReadings
|
||||||
|
* double min
|
||||||
|
* double max
|
||||||
|
**/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (c) <year> <copyright holders>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AVGSTD_H
|
||||||
|
#define AVGSTD_H
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
class AvgStd {
|
||||||
|
public:
|
||||||
|
float getMean();
|
||||||
|
float getStd();
|
||||||
|
float getMin();
|
||||||
|
float getMax();
|
||||||
|
float getVariance();
|
||||||
|
unsigned int getN();
|
||||||
|
void reset();
|
||||||
|
void addReading(float);
|
||||||
|
void checkAndAddReading(float);
|
||||||
|
void setRejectionSigma(float);
|
||||||
|
int getTrend();
|
||||||
|
void setTrendInterval(int);
|
||||||
|
void setSamplingInterval(int);
|
||||||
|
AvgStd();
|
||||||
|
private:
|
||||||
|
float min, max, var, avg, r_sigma;
|
||||||
|
unsigned int N;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
extern unsigned int __bss_end;
|
||||||
|
extern unsigned int __heap_start;
|
||||||
|
extern void *__brkval;
|
||||||
|
|
||||||
|
#include "MemoryFree.h"
|
||||||
|
|
||||||
|
int freeMemory() {
|
||||||
|
int free_memory;
|
||||||
|
|
||||||
|
if((int)__brkval == 0)
|
||||||
|
free_memory = ((int)&free_memory) - ((int)&__bss_end);
|
||||||
|
else
|
||||||
|
free_memory = ((int)&free_memory) - ((int)__brkval);
|
||||||
|
|
||||||
|
return free_memory;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// memoryFree header
|
||||||
|
|
||||||
|
#ifndef MEMORY_FREE_H
|
||||||
|
#define MEMORY_FREE_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int freeMemory();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Kristian Klein Jacobsen
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Kristian Klein Jacobsen
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PushButton.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#define IDLE 0
|
||||||
|
#define ACTIVE 1
|
||||||
|
#define CLICKED 2
|
||||||
|
#define DOUBLE_CLICKED 3
|
||||||
|
#define RELEASED 4
|
||||||
|
#define FIRST_HELD 5
|
||||||
|
#define HELD 6
|
||||||
|
|
||||||
|
PushButton::PushButton(int pin)
|
||||||
|
{
|
||||||
|
pin_ = pin;
|
||||||
|
state_ = IDLE;
|
||||||
|
debounced_ = true;
|
||||||
|
doubleClickable_ = true;
|
||||||
|
activeLogic_ = true;
|
||||||
|
debounceTime_ = 10;
|
||||||
|
holdTime_ = 2000;
|
||||||
|
doubleClickTime_ = 300;
|
||||||
|
lastClickTime_ = 0;
|
||||||
|
lastReleaseTime_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushButton::update()
|
||||||
|
{
|
||||||
|
switch (state_)
|
||||||
|
{
|
||||||
|
case IDLE:
|
||||||
|
if (debounced_)
|
||||||
|
{
|
||||||
|
if (isActive()) // Button clicked
|
||||||
|
{
|
||||||
|
if (doubleClickable_ && millis() - lastClickTime_ < doubleClickTime_)
|
||||||
|
{
|
||||||
|
state_ = DOUBLE_CLICKED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state_ = CLICKED;
|
||||||
|
}
|
||||||
|
|
||||||
|
debounced_ = false;
|
||||||
|
lastClickTime_ = millis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (millis() - lastReleaseTime_ > debounceTime_)
|
||||||
|
{
|
||||||
|
debounced_ = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACTIVE:
|
||||||
|
if (debounced_) // Only check button again when it has been debounced
|
||||||
|
{
|
||||||
|
if (!isActive()) // Button not active, hence released
|
||||||
|
{
|
||||||
|
state_ = RELEASED;
|
||||||
|
}
|
||||||
|
else if (millis() - lastClickTime_ > holdTime_) // Button held
|
||||||
|
{
|
||||||
|
state_ = FIRST_HELD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (millis() - lastClickTime_ > debounceTime_) // Check if debounce time has passed
|
||||||
|
{
|
||||||
|
debounced_ = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLICKED:
|
||||||
|
case DOUBLE_CLICKED:
|
||||||
|
state_ = ACTIVE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RELEASED:
|
||||||
|
state_ = IDLE;
|
||||||
|
debounced_ = false;
|
||||||
|
lastReleaseTime_ = millis();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FIRST_HELD:
|
||||||
|
state_ = HELD;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HELD:
|
||||||
|
if (!isActive())
|
||||||
|
{
|
||||||
|
state_ = RELEASED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: // This should never execute
|
||||||
|
state_ = IDLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PushButton::isActive()
|
||||||
|
{
|
||||||
|
return (digitalRead(pin_) == activeLogic_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PushButton::isClicked()
|
||||||
|
{
|
||||||
|
return (state_ == CLICKED);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PushButton::isDoubleClicked()
|
||||||
|
{
|
||||||
|
if (doubleClickable_)
|
||||||
|
{
|
||||||
|
return (state_ == DOUBLE_CLICKED);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PushButton::isHeld()
|
||||||
|
{
|
||||||
|
return (state_ == FIRST_HELD);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PushButton::isReleased()
|
||||||
|
{
|
||||||
|
return (state_ == RELEASED);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushButton::disableDoubleClick()
|
||||||
|
{
|
||||||
|
doubleClickable_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushButton::enableDoubleClick()
|
||||||
|
{
|
||||||
|
doubleClickable_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushButton::setDebounceTime(int ms)
|
||||||
|
{
|
||||||
|
debounceTime_ = ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushButton::setHoldTime(int ms)
|
||||||
|
{
|
||||||
|
holdTime_ = ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushButton::setDoubleClickTime(int ms)
|
||||||
|
{
|
||||||
|
doubleClickTime_ = ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushButton::setActiveLogic(int high_or_low)
|
||||||
|
{
|
||||||
|
activeLogic_ = high_or_low;
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Kristian Klein Jacobsen
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PUSHBUTTON_H
|
||||||
|
#define PUSHBUTTON_H
|
||||||
|
|
||||||
|
class PushButton
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PushButton(int pin);
|
||||||
|
void update();
|
||||||
|
bool isActive();
|
||||||
|
bool isClicked();
|
||||||
|
bool isDoubleClicked();
|
||||||
|
bool isHeld();
|
||||||
|
bool isReleased();
|
||||||
|
void disableDoubleClick();
|
||||||
|
void enableDoubleClick();
|
||||||
|
void setDebounceTime(int ms);
|
||||||
|
void setHoldTime(int ms);
|
||||||
|
void setDoubleClickTime(int ms);
|
||||||
|
void setActiveLogic(int high_or_low);
|
||||||
|
private:
|
||||||
|
int state_;
|
||||||
|
long lastClickTime_;
|
||||||
|
long lastReleaseTime_;
|
||||||
|
int pin_;
|
||||||
|
bool doubleClickable_;
|
||||||
|
bool activeLogic_;
|
||||||
|
bool debounced_;
|
||||||
|
int debounceTime_;
|
||||||
|
int holdTime_;
|
||||||
|
int doubleClickTime_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
name=PushButton
|
||||||
|
version=1.0.0
|
||||||
|
author=Kristian Klein Jacobsen <kristian.klein90@gmail.com>
|
||||||
|
maintainer=Kristian Klein Jacobsen <kristian.klein90@gmail.com>
|
||||||
|
sentence=Makes it much easier for you to use push buttons in your application.
|
||||||
|
paragraph=Easily check for events such as click, double-click or hold on a push button, without worrying about debouncing or blocking the rest of your application with a delay.
|
||||||
|
category=Signal Input/Output
|
||||||
|
url=http://github.com/kristianklein/PushButton
|
||||||
|
architectures=*
|
||||||
|
includes=PushButton.h
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,259 @@
|
|||||||
|
#ifndef SDBlock_h
|
||||||
|
#define SDBlock_h
|
||||||
|
|
||||||
|
// #define USE_SDCORE
|
||||||
|
#define USE_SD2CARD
|
||||||
|
// #define USE_SDFS
|
||||||
|
|
||||||
|
#ifdef USE_SDCORE
|
||||||
|
#include <SDCore.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_SD2CARD
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <SD.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_SDFS
|
||||||
|
#include <SdFs.h>
|
||||||
|
// if (!sd.card()->readSector(0, (uint8_t*)&mbr)) {
|
||||||
|
#define SD_CS_PIN SS
|
||||||
|
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <TimeLib.h>
|
||||||
|
#include <CRC32.h>
|
||||||
|
#include "SDBlockData.h"
|
||||||
|
|
||||||
|
// Define Callback with buffers
|
||||||
|
// typedef void (*CallbackFunction) (uint32_t recId, uint32_t blockId, uint32_t blockCount, void *buf, uint16_t size);
|
||||||
|
|
||||||
|
#define ERASE_SIZE 262144L
|
||||||
|
|
||||||
|
class SDBlock {
|
||||||
|
public:
|
||||||
|
void begin(uint32_t dId);
|
||||||
|
void end();
|
||||||
|
|
||||||
|
bool debug;
|
||||||
|
Stream *stream;
|
||||||
|
|
||||||
|
#ifdef USE_SD2CARD
|
||||||
|
Sd2Card sd;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_SDFS
|
||||||
|
// SdFat sd;
|
||||||
|
// SdExFat sd;
|
||||||
|
SdCardFactory cardFactory;
|
||||||
|
SdFs sd;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint32_t size;
|
||||||
|
|
||||||
|
// Erase card etc
|
||||||
|
SDBlock_Allocation* allocation;
|
||||||
|
SDBlock_Metadata* metadata;
|
||||||
|
SDBlock_LogLines* loglines;
|
||||||
|
SDBlock_Queue* queue;
|
||||||
|
SDBlock_Block* block;
|
||||||
|
|
||||||
|
// Thew actual Buffer
|
||||||
|
byte buffer[SDBLOCK_SECTOR_SIZE] = {0x00};
|
||||||
|
|
||||||
|
bool getMBR();
|
||||||
|
|
||||||
|
bool _sdinit();
|
||||||
|
bool cardIsOpen();
|
||||||
|
bool cardErase();
|
||||||
|
bool cardOpen(uint32_t cId, bool format = false);
|
||||||
|
bool cardClose();
|
||||||
|
void cardForceClose();
|
||||||
|
void checkInternals();
|
||||||
|
|
||||||
|
bool read(unsigned long address_in);
|
||||||
|
bool write(unsigned long address_in);
|
||||||
|
|
||||||
|
bool allocationDefault();
|
||||||
|
bool allocationUpdate();
|
||||||
|
bool allocationWrite();
|
||||||
|
bool allocationValid();
|
||||||
|
bool allocationRead();
|
||||||
|
|
||||||
|
void crcUpdate();
|
||||||
|
bool crcCheck();
|
||||||
|
void crcSet();
|
||||||
|
|
||||||
|
bool validRange(char *str, uint32_t test, uint32_t start, uint32_t max);
|
||||||
|
|
||||||
|
bool dataIsOpen();
|
||||||
|
bool dataOpen(uint32_t recId);
|
||||||
|
bool dataClose(bool output);
|
||||||
|
bool dataPrepare(void* in = NULL, uint16_t size = 0);
|
||||||
|
bool dataWrite(void* in = NULL, uint16_t size = 0);
|
||||||
|
|
||||||
|
bool metadataPrepare(void* in = NULL, uint16_t size = 0);
|
||||||
|
bool metadataWrite(void* in = NULL, uint16_t size = 0);
|
||||||
|
bool metadataRead(uint32_t fromEnd);
|
||||||
|
bool metadataReadBLK(uint32_t address_in);
|
||||||
|
bool metadataUpdateStatus(uint32_t address_in, uint32_t record_in, uint32_t status_in);
|
||||||
|
void metadataList(uint32_t fromEnd, uint32_t num, Print* altstream = NULL); //, CallbackFunction cb = NULL);
|
||||||
|
|
||||||
|
bool resultsRead(uint32_t adddress);
|
||||||
|
bool resultsReadBLK(uint32_t adddress);
|
||||||
|
|
||||||
|
// Status Updats, note: BLK - means actual block (where ever it is)
|
||||||
|
/*
|
||||||
|
bool metadataStatusBLK(uint32_t block, uint32_t status);
|
||||||
|
bool dataStatusBLK(uint32_t block, uint32_t status);
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint32_t metadataCount();
|
||||||
|
|
||||||
|
// void dataList(unsigned long address, Print* altstream = NULL, CallbackFunction metadata_cb = NULL, CallbackFunction data_cb = NULL);
|
||||||
|
|
||||||
|
bool singlePrepare(void* in = NULL, uint16_t size = 0);
|
||||||
|
bool singleWrite(void* in = NULL, uint16_t size = 0);
|
||||||
|
bool singleRead(uint32_t fromEnd);
|
||||||
|
uint32_t singleCount();
|
||||||
|
|
||||||
|
void setDeviceId(uint32_t dId);
|
||||||
|
void setRecordId(uint32_t rId);
|
||||||
|
|
||||||
|
void setAutoFormat(bool in);
|
||||||
|
bool getAutoFormat();
|
||||||
|
|
||||||
|
// Very basic queue
|
||||||
|
bool queuePrepare(uint32_t status, void* in = NULL, uint16_t in_size = 0, void* out = NULL, uint16_t out_size = 0);
|
||||||
|
bool queueWrite(uint32_t status = 0, void* in = NULL, uint16_t in_size = 0, void* out = NULL, uint16_t out_size = 0);
|
||||||
|
|
||||||
|
// Update queue - fromEnd - like Single - include status cahnge, and optional data out
|
||||||
|
bool queueUpdate(uint32_t fromEnd, uint32_t status, void* out = NULL, uint16_t out_size = 0);
|
||||||
|
bool queueRead(uint32_t fromEnd);
|
||||||
|
uint32_t queueCount();
|
||||||
|
|
||||||
|
uint32_t getDataNext(); // Get the next block for manual reading
|
||||||
|
uint32_t getMetadataNext(); // Get the next block for manual reading
|
||||||
|
uint8_t getCardId(); // Get the next block for manual reading
|
||||||
|
|
||||||
|
uint32_t getMetadataFirst(); // Get the next block for manual reading
|
||||||
|
uint32_t getDataFirst(); // Get the next block for manual reading
|
||||||
|
/*
|
||||||
|
|
||||||
|
Logging:
|
||||||
|
|
||||||
|
Logging:
|
||||||
|
- Can be implemented completely outside of here.
|
||||||
|
- And just use single or even a pecial set of singles.
|
||||||
|
|
||||||
|
Basics:
|
||||||
|
- Balance memory with Blocks - a full 512 byte block in
|
||||||
|
memory is probably too much for logging.
|
||||||
|
- logAdd(level, string);
|
||||||
|
. Return something.... to say buffer full, need to writeBlock
|
||||||
|
|
||||||
|
- logAuto(); // Automatiaclly prepare, write, etc.
|
||||||
|
// Maybe pass param true, says write even if
|
||||||
|
// only one log in the queue
|
||||||
|
|
||||||
|
- logPrepare();
|
||||||
|
- logWrite();
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Queue. - standard queue commands, work like Single
|
||||||
|
/*
|
||||||
|
|
||||||
|
More advanced Queue Reader
|
||||||
|
|
||||||
|
- Next Low|High, Type
|
||||||
|
e.g. High Iridium Send
|
||||||
|
then low Iridium Send
|
||||||
|
Iridium receive
|
||||||
|
Slow to find?
|
||||||
|
Status can be used for all the lookups
|
||||||
|
- 32 bit,
|
||||||
|
8 bit type
|
||||||
|
8 bit status
|
||||||
|
16 bit info (e.g. why it failed, or number of blocsk)
|
||||||
|
|
||||||
|
Size vs Data
|
||||||
|
|
||||||
|
WII4 Data
|
||||||
|
* 2 blocks (two transmits)
|
||||||
|
* 299 bytes - 6 blocks
|
||||||
|
* 336 bytes - 7 blocsk
|
||||||
|
* AKA - two blocks on the SD Card
|
||||||
|
So we do have to use a whole SD Card block
|
||||||
|
|
||||||
|
Early optomisation is death
|
||||||
|
* Use CaptureMode code or Iridium code to manage.
|
||||||
|
|
||||||
|
* Simplified walking
|
||||||
|
queueRead(rec);
|
||||||
|
|
||||||
|
if (status - in range - ie. not sent, right type)
|
||||||
|
sendIridium
|
||||||
|
recordResults back in records
|
||||||
|
queueUpdate(rec, X,Y,Z)
|
||||||
|
|
||||||
|
rec++;
|
||||||
|
|
||||||
|
if (rec > 10000) {
|
||||||
|
// That will do. exit
|
||||||
|
}
|
||||||
|
|
||||||
|
queueNextHigh(X)
|
||||||
|
|
||||||
|
queuePrepare
|
||||||
|
queueWrite
|
||||||
|
queueRead - like single, from end
|
||||||
|
queueReadHigh - Read most resent high
|
||||||
|
queueReadLow - Read most resent low
|
||||||
|
queueUpdate(id, stuff - eg status)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t dataLast;
|
||||||
|
uint32_t metadataLast;
|
||||||
|
uint32_t queueLast;
|
||||||
|
uint32_t singleLast;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
byte response; // Resuable for all read/write
|
||||||
|
uint32_t crc;
|
||||||
|
uint32_t address_local; // Temporary location of calculated addresses
|
||||||
|
uint32_t count; // Reusable counter (for loops)
|
||||||
|
|
||||||
|
bool autoFormat; // Automatically format on failure
|
||||||
|
|
||||||
|
// Allocation tabler
|
||||||
|
uint32_t dataBlockNext; // Next, becasue first record is 0, so initilaly we write there
|
||||||
|
uint32_t metadataBlockNext; // And of course where is the Metadata
|
||||||
|
uint32_t singleBlockNext; // And of course where is the Metadata
|
||||||
|
uint32_t loglinesBlockNext; // And of course where is the Metadata
|
||||||
|
uint32_t queueBlockNext; // And of course where is the Metadata
|
||||||
|
|
||||||
|
// Card read, open and valid
|
||||||
|
bool valid;
|
||||||
|
|
||||||
|
// Current DATA
|
||||||
|
uint32_t dataBlockStart;
|
||||||
|
uint32_t dataBlockCurrent;
|
||||||
|
uint32_t dataBlockRecordId;
|
||||||
|
|
||||||
|
uint32_t metadata_dataBlockStart;
|
||||||
|
uint32_t metadata_dataBlocks;
|
||||||
|
|
||||||
|
uint32_t metadata_resultsBlockStart;
|
||||||
|
uint32_t metadata_resultsBlocks;
|
||||||
|
|
||||||
|
uint32_t cardId;
|
||||||
|
uint32_t deviceId;
|
||||||
|
uint32_t recordId;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern SDBlock sdBlock;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,214 @@
|
|||||||
|
#ifndef SDBlockData_h
|
||||||
|
#define SDBlockData_h
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Misc notes:
|
||||||
|
|
||||||
|
* Structure of all blocks:
|
||||||
|
* Block type
|
||||||
|
* Free form set of fields
|
||||||
|
* Free block to be used
|
||||||
|
* Status field - re-writable
|
||||||
|
* CRC32 - TODO, consider leaving status out of the CRC
|
||||||
|
(although only for time, as the block has to be in memory to change the status)
|
||||||
|
|
||||||
|
Sizes:
|
||||||
|
* 32 Bit blocks allows for up to 2000 GB of Storage
|
||||||
|
* Where as 32 Bit bytes (when moving an address) allows only 4GB
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
|
||||||
|
* Status based searcher - like that being considered for Queues
|
||||||
|
* Find me next with Status X or bitmap or < or >
|
||||||
|
* But.... keep where we were up to to, so we don't have to serarh/load all them blocks again
|
||||||
|
* Consider this only for memory for now.
|
||||||
|
|
||||||
|
Notes on WII5
|
||||||
|
|
||||||
|
|
||||||
|
One Run = 40960 records. 15 Per Sector
|
||||||
|
2730 data packets
|
||||||
|
|
||||||
|
Total packets = 62500000
|
||||||
|
/ runs = 22893
|
||||||
|
|
||||||
|
4 per hour, 24 hours per day
|
||||||
|
238 days
|
||||||
|
|
||||||
|
2 Cards - actually = 476
|
||||||
|
|
||||||
|
So make it 150 days
|
||||||
|
14400 records
|
||||||
|
|
||||||
|
Data Size = 14400 * 2730 = 39312000 = 62%
|
||||||
|
|
||||||
|
Therefore Metadata minimum 14400, up to 20000
|
||||||
|
|
||||||
|
Queue - could have up to 8 messages per metadata, so 20000*8 = 160000
|
||||||
|
|
||||||
|
Number Start End Size Type File system Flags
|
||||||
|
1 2048s 1251327s 1249280s primary fat32 lba
|
||||||
|
|
||||||
|
|
||||||
|
sudo dd if=/dev/mmcblk2 of=block_fat1.img bs=512 count=1251328
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SDBLOCK_SECTOR_SIZE 512
|
||||||
|
|
||||||
|
// XXX Add super block information
|
||||||
|
// Bytes:
|
||||||
|
// 1 = Fixed = SDBlock, always 10101111
|
||||||
|
// 2 = Version of SDBlock, 00000001
|
||||||
|
// 3 = Block type & Bersion 1, 2, 3,4 + 1
|
||||||
|
#define SDBLOCK_TYPE_SDBLOCK 101
|
||||||
|
#define SDBLOCK_TYPE_SDBLOCK_VERSION 1
|
||||||
|
#define SDBLOCK_TYPE_ALLOCATION 1
|
||||||
|
#define SDBLOCK_TYPE_ALLOCATION_VERSION 1
|
||||||
|
#define SDBLOCK_TYPE_ALLOCATION_FULL ((SDBLOCK_TYPE_SDBLOCK << 24) | (SDBLOCK_TYPE_SDBLOCK_VERSION << 16) | (SDBLOCK_TYPE_ALLOCATION << 8) | SDBLOCK_TYPE_ALLOCATION_VERSION)
|
||||||
|
#define SDBLOCK_TYPE_METADATA 2
|
||||||
|
#define SDBLOCK_TYPE_METADATA_VERSION 1
|
||||||
|
#define SDBLOCK_TYPE_METADATA_FULL ((SDBLOCK_TYPE_SDBLOCK << 24) | (SDBLOCK_TYPE_SDBLOCK_VERSION << 16) | (SDBLOCK_TYPE_METADATA << 8) | SDBLOCK_TYPE_METADATA_VERSION)
|
||||||
|
#define SDBLOCK_TYPE_LOGLINES 3
|
||||||
|
#define SDBLOCK_TYPE_LOGLINES_VERSION 1
|
||||||
|
#define SDBLOCK_TYPE_LOGLINES_FULL ((SDBLOCK_TYPE_SDBLOCK << 24) | (SDBLOCK_TYPE_SDBLOCK_VERSION << 16) | (SDBLOCK_TYPE_LOGLINES << 8) | SDBLOCK_TYPE_LOGLINES_VERSION)
|
||||||
|
#define SDBLOCK_TYPE_SINGLE 4
|
||||||
|
#define SDBLOCK_TYPE_SINGLE_VERSION 1
|
||||||
|
#define SDBLOCK_TYPE_SINGLE_FULL ((SDBLOCK_TYPE_SDBLOCK << 24) | (SDBLOCK_TYPE_SDBLOCK_VERSION << 16) | (SDBLOCK_TYPE_SINGLE << 8) | SDBLOCK_TYPE_SINGLE_VERSION)
|
||||||
|
#define SDBLOCK_TYPE_BLOCK 5
|
||||||
|
#define SDBLOCK_TYPE_BLOCK_VERSION 1
|
||||||
|
#define SDBLOCK_TYPE_BLOCK_FULL ((SDBLOCK_TYPE_SDBLOCK << 24) | (SDBLOCK_TYPE_SDBLOCK_VERSION << 16) | (SDBLOCK_TYPE_BLOCK << 8) | SDBLOCK_TYPE_BLOCK_VERSION)
|
||||||
|
#define SDBLOCK_TYPE_QUEUE 5
|
||||||
|
#define SDBLOCK_TYPE_QUEUE_VERSION 1
|
||||||
|
#define SDBLOCK_TYPE_QUEUE_FULL ((SDBLOCK_TYPE_SDBLOCK << 24) | (SDBLOCK_TYPE_SDBLOCK_VERSION << 16) | (SDBLOCK_TYPE_QUEUE << 8) | SDBLOCK_TYPE_QUEUE_VERSION)
|
||||||
|
|
||||||
|
|
||||||
|
// Special - Block Offset ! Where does this start
|
||||||
|
#define SDBLOCK_OFFSET (uint32_t)1300000 // Absolute position start of allocation table
|
||||||
|
#define SDBLOCK_MAX (uint32_t)62500000
|
||||||
|
#define SDBLOCK_ALLOCATION_MAX (uint32_t)2 // How many we can have
|
||||||
|
#define SDBLOCK_METADATA_MAX (uint32_t)20000 // How many we can have
|
||||||
|
#define SDBLOCK_SINGLE_MAX (uint32_t)20000 // How many we can have
|
||||||
|
#define SDBLOCK_LOGLINES_MAX (uint32_t)10000 // How many we can have
|
||||||
|
#define SDBLOCK_QUEUE_MAX (uint32_t)300000 // How many we can have
|
||||||
|
#define SDBLOCK_DATA_MAX (uint32_t)45000000 // How many we can have
|
||||||
|
|
||||||
|
#define SDBLOCK_ACTUAL_ALLOCATION (uint32_t)SDBLOCK_OFFSET
|
||||||
|
#define SDBLOCK_ACTUAL_METADATA (uint32_t)(SDBLOCK_OFFSET + SDBLOCK_ALLOCATION_MAX)
|
||||||
|
#define SDBLOCK_ACTUAL_SINGLE (uint32_t)(SDBLOCK_OFFSET + SDBLOCK_ALLOCATION_MAX + SDBLOCK_METADATA_MAX)
|
||||||
|
#define SDBLOCK_ACTUAL_LOGLINES (uint32_t)(SDBLOCK_OFFSET + SDBLOCK_ALLOCATION_MAX + SDBLOCK_METADATA_MAX + SDBLOCK_SINGLE_MAX)
|
||||||
|
#define SDBLOCK_ACTUAL_QUEUE (uint32_t)(SDBLOCK_OFFSET + SDBLOCK_ALLOCATION_MAX + SDBLOCK_METADATA_MAX + SDBLOCK_SINGLE_MAX + SDBLOCK_LOGLINES_MAX)
|
||||||
|
#define SDBLOCK_ACTUAL_DATA (uint32_t)(SDBLOCK_OFFSET + SDBLOCK_ALLOCATION_MAX + SDBLOCK_METADATA_MAX + SDBLOCK_SINGLE_MAX + SDBLOCK_LOGLINES_MAX + SDBLOCK_QUEUE_MAX)
|
||||||
|
|
||||||
|
// ALLOCATION Block
|
||||||
|
#define SDBLOCK_ALLOCATION_DATA_SIZE 460
|
||||||
|
typedef struct {
|
||||||
|
// 12
|
||||||
|
uint32_t blockType;
|
||||||
|
uint32_t deviceId; // Device and Record
|
||||||
|
uint32_t recordId; // In this case, it will be the last actually used one
|
||||||
|
uint32_t cardId; // In this case, it will be the last actually used one
|
||||||
|
|
||||||
|
// 16
|
||||||
|
time_t currentTime; // Last updated?
|
||||||
|
|
||||||
|
// 16
|
||||||
|
uint32_t metadataBlockNext; // And of course where is the Metadata
|
||||||
|
uint32_t singleBlockNext; // And of course where is the Metadata
|
||||||
|
uint32_t loglinesBlockNext; // And of course where is the Metadata
|
||||||
|
uint32_t dataBlockNext; // Next, becasue first record is 0, so initilaly we write there
|
||||||
|
|
||||||
|
uint32_t queueBlockNext; // Next, becasue first record is 0, so initilaly we write there
|
||||||
|
uint32_t queueHighDone; // What queue high have we done, read from here
|
||||||
|
uint32_t queueLowDone; // What queue low have we done, read from here
|
||||||
|
|
||||||
|
uint8_t data[SDBLOCK_ALLOCATION_DATA_SIZE]; // Calcu;ate
|
||||||
|
|
||||||
|
uint32_t crc;
|
||||||
|
} SDBlock_Allocation;
|
||||||
|
|
||||||
|
// METADATA Block
|
||||||
|
#define SDBLOCK_METADATA_DATA_SIZE 476
|
||||||
|
typedef struct {
|
||||||
|
// 12
|
||||||
|
uint32_t blockType;
|
||||||
|
uint32_t deviceId; // Device and Record
|
||||||
|
uint32_t recordId; // OR recordCount
|
||||||
|
|
||||||
|
// 8
|
||||||
|
uint32_t dataBlockStart; // DATA: Where does it start
|
||||||
|
uint32_t dataBlocks; // DATA: Number of blocks, 0 being none at all
|
||||||
|
|
||||||
|
// Keep these variables outside of this structure - see wii5Metadata
|
||||||
|
char data[SDBLOCK_METADATA_DATA_SIZE];
|
||||||
|
|
||||||
|
// 8
|
||||||
|
uint32_t resultsBlockStart; // RESULTS: Where does it start
|
||||||
|
uint32_t resultsBlocks; // RESULTS: Number of blocks, 0 being none at all
|
||||||
|
|
||||||
|
// 8
|
||||||
|
uint32_t status; // WII5 example - 0=NoResults, 1=Results, 4=Results+Sent, 5=
|
||||||
|
/*
|
||||||
|
|
||||||
|
uint8_t
|
||||||
|
. ?
|
||||||
|
. ?
|
||||||
|
. > 0 = Number of attempts sending - 1111 = Success
|
||||||
|
. > 0 = Data saved
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint32_t crc;
|
||||||
|
} SDBlock_Metadata;
|
||||||
|
|
||||||
|
#define SDBLOCK_LOG_DATA_SIZE 42
|
||||||
|
#define SDBLOCK_LOG_DATA_LINES 10
|
||||||
|
|
||||||
|
// LogLine
|
||||||
|
typedef struct {
|
||||||
|
time_t logTime;
|
||||||
|
// NOTE: Most of these integers, normally 1 byte, are set to 4 bytes for packing.
|
||||||
|
uint32_t logLevel;
|
||||||
|
char data[SDBLOCK_LOG_DATA_SIZE];
|
||||||
|
} SDBlock_LogLine;
|
||||||
|
|
||||||
|
// LOG Block
|
||||||
|
typedef struct {
|
||||||
|
uint32_t blockType;
|
||||||
|
uint32_t recordId; // OR recordCount
|
||||||
|
|
||||||
|
SDBlock_LogLine lines[SDBLOCK_LOG_DATA_LINES];
|
||||||
|
|
||||||
|
uint32_t crc;
|
||||||
|
} SDBlock_LogLines;
|
||||||
|
|
||||||
|
#define SDBLOCK_QUEUE_DATAIN_SIZE 400
|
||||||
|
#define SDBLOCK_QUEUE_DATAOUT_SIZE 92
|
||||||
|
// Queue
|
||||||
|
typedef struct {
|
||||||
|
uint32_t blockType; // 4
|
||||||
|
// deviceId, recordId ?
|
||||||
|
|
||||||
|
time_t currentTime;
|
||||||
|
uint32_t priority;
|
||||||
|
char dataIn[SDBLOCK_QUEUE_DATAIN_SIZE];
|
||||||
|
char dataOut[SDBLOCK_QUEUE_DATAOUT_SIZE];
|
||||||
|
uint32_t status;
|
||||||
|
uint32_t crc;
|
||||||
|
} SDBlock_Queue;
|
||||||
|
|
||||||
|
// BLOCK - Let us make them all the same !
|
||||||
|
#define SDBLOCK_BLOCK_DATA_SIZE 496
|
||||||
|
typedef struct {
|
||||||
|
uint32_t blockType; // 4
|
||||||
|
// Note: deviceId etc can all be taken from Metadata.
|
||||||
|
uint32_t recordId; // Important to group these together.
|
||||||
|
|
||||||
|
uint8_t data[SDBLOCK_BLOCK_DATA_SIZE]; // All the data in the middle
|
||||||
|
|
||||||
|
uint32_t status;
|
||||||
|
uint32_t crc;
|
||||||
|
} SDBlock_Block;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// 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 pio_main.cpp
|
||||||
|
* @brief PlatformIO entry shim.
|
||||||
|
*
|
||||||
|
* PlatformIO only auto-detects a sketch (`*.ino`) at the top level of its
|
||||||
|
* source directory, but this project's sketch lives at
|
||||||
|
* `app/wii5_buoy/wii5_buoy.ino`. This shim pulls that sketch into the
|
||||||
|
* PlatformIO build (where `setup()`/`loop()` are defined).
|
||||||
|
*
|
||||||
|
* It is gated on the `PLATFORMIO` macro (defined only by PlatformIO) so that
|
||||||
|
* the arduino-cli build — which compiles the repo root as a flat library and
|
||||||
|
* the .ino as the sketch — never sees a second definition of setup()/loop().
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(PLATFORMIO)
|
||||||
|
#include "app/wii5_buoy/wii5_buoy.ino"
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
; SPDX-License-Identifier: Apache-2.0
|
||||||
|
; Copyright (c) 2012-2024 Scott Penrose <scottp@dd.com.au> and WII5 Buoy contributors
|
||||||
|
;
|
||||||
|
; PlatformIO build configuration for the WII5 Buoy firmware.
|
||||||
|
; This sits alongside the existing arduino-cli flow (tools/build_local.sh);
|
||||||
|
; both can build the same sources, which stay in place at the repo root.
|
||||||
|
;
|
||||||
|
; Usage:
|
||||||
|
; pio run -e wii5_buoy # compile
|
||||||
|
; pio run -e wii5_buoy -t upload # compile + flash
|
||||||
|
; pio device monitor -e wii5_buoy # serial console @ 230400
|
||||||
|
;
|
||||||
|
; See platformio.org for the full reference.
|
||||||
|
|
||||||
|
[platformio]
|
||||||
|
; Sources live at the repo root, not in a src/ dir. Compile them in place.
|
||||||
|
src_dir = .
|
||||||
|
|
||||||
|
[env:wii5_buoy]
|
||||||
|
platform = atmelavr
|
||||||
|
framework = arduino
|
||||||
|
|
||||||
|
; Custom board: ATmega2560, 3V3, 11.0592 MHz crystal, serial bootloader @ 230400.
|
||||||
|
; Definition lives in boards/wii5_v2_2560.json (auto-discovered).
|
||||||
|
board = wii5_v2_2560
|
||||||
|
|
||||||
|
; Upload over the Arduino serial bootloader (avrdude -c arduino).
|
||||||
|
upload_protocol = arduino
|
||||||
|
upload_speed = 230400
|
||||||
|
; upload_port = /dev/ttyUSB0 ; uncomment / override, or rely on auto-detect
|
||||||
|
monitor_speed = 230400
|
||||||
|
|
||||||
|
; Compile the firmware sources at the repo root. The "*.cpp" glob is
|
||||||
|
; non-recursive, so it matches only the root-level WII5*.cpp plus pio_main.cpp
|
||||||
|
; (the entry shim) and naturally excludes app/, test/, tools/ and doc/.
|
||||||
|
; The entry sketch (app/wii5_buoy/wii5_buoy.ino) is pulled in by pio_main.cpp.
|
||||||
|
build_src_filter =
|
||||||
|
+<*.cpp>
|
||||||
|
|
||||||
|
; The project's own headers are included with angle brackets (<WII5.h>, ...),
|
||||||
|
; so the repo root must be on the include path. Software version/commit are
|
||||||
|
; normally injected by tools/build_local.sh; default them here.
|
||||||
|
build_flags =
|
||||||
|
-I.
|
||||||
|
; Board-variant macros that the arduino-cli custom board (WII:avr) injected:
|
||||||
|
-D__WII5_V02__ ; selects WII5_board_v2.h in WII5_board.h
|
||||||
|
-DF_CPU_11 ; 11.0592 MHz timing -> 230400 console / 115200 IMU baud
|
||||||
|
; Older Arduino AVR cores exposed NUM_PINS; current cores use NUM_DIGITAL_PINS.
|
||||||
|
-DNUM_PINS=NUM_DIGITAL_PINS
|
||||||
|
-DWII5_SOFTWARE_VERSION=\"WII5Buoy_dev\"
|
||||||
|
-DWII5_SOFTWARE_COMMIT=\"dev\"
|
||||||
|
|
||||||
|
; Public libraries pulled from the PlatformIO registry. Scott's own libraries
|
||||||
|
; (AvgStd, PushButton, MemoryFree, SDBlock) are vendored under lib/ instead.
|
||||||
|
lib_deps =
|
||||||
|
paulstoffregen/Time
|
||||||
|
mikalhart/TinyGPSPlus
|
||||||
|
milesburton/DallasTemperature
|
||||||
|
paulstoffregen/OneWire
|
||||||
|
pfeerick/elapsedMillis
|
||||||
|
rocketscream/Low-Power
|
||||||
|
sparkfun/IridiumSBDi2c
|
||||||
|
thijse/EEPROMEx
|
||||||
|
bakercp/CRC32
|
||||||
|
arduino-libraries/SD
|
||||||
|
adafruit/RTClib
|
||||||
|
|
||||||
|
; LoRa-enabled variant (experimental). This path additionally depends on the
|
||||||
|
; Sh3dNode networking stack (sh3dNodeNetwork / SH3D_NODE_Packet_* / RH_RF95),
|
||||||
|
; which is NOT bundled in this repository, so the env does not build as-is.
|
||||||
|
; RadioHead is also GPLv2 (dual-licensed); binaries built from it inherit GPLv2
|
||||||
|
; terms. Enable once the Sh3dNode library is available, e.g.:
|
||||||
|
;
|
||||||
|
; [env:wii5_buoy_lora]
|
||||||
|
; extends = env:wii5_buoy
|
||||||
|
; build_flags =
|
||||||
|
; ${env:wii5_buoy.build_flags}
|
||||||
|
; -DWII5_RADIO_LORA
|
||||||
|
; lib_deps =
|
||||||
|
; ${env:wii5_buoy.lib_deps}
|
||||||
|
; mikem/RadioHead
|
||||||
|
; <path-or-url-to-Sh3dNode-library>
|
||||||
Reference in New Issue
Block a user