Home › Forums › Mayfly Data Logger › Mayfly sketch compiles, seems to upload, but doesn’t
- This topic has 21 replies, 2 voices, and was last updated 2023-08-16 at 1:03 PM by Sedhead.
-
AuthorPosts
-
-
2023-08-04 at 6:13 PM #18002
I am using VSCode and Platformio to upload sketches to my Mayfly boards. The sketches compiled and uploaded fine two weeks ago. Today, when I went to deploy the sensors, the code compiled fine and it even looked like it uploaded fine, except that the upload was way too fast. Usually there is a bit of a lag as the code is being written to the board and that did not happen. The message after the upload said it was ‘successful’ but no sketch got uploaded to the Mayfly. Here is a list of things that I tried in no particular order:
- I double-checked my USB port and it was good to go.
- I made sure I was working with the correct platformio.ini and that it was in the right place in the folder set up.
- I uploaded simple Arduino code (‘blink’) and it uploaded and ran fine.
- I tested it on both a v. 0.5b and v. 1.1 board and it wouldn’t upload on either.
- I changed my USB cables to make sure I was using our top quality ones.
- I ran “clean” on platformio and even made sure that I had no duplicate libraries in my .pio libdeps folder.
- I switched the mayflys on and off.
I’m happy to share my code with y’all, but this doesn’t seem to be related to code. Wondering if VSCode or Platformio went through an update that has tweaked things. Any help would be greatly appreciated.
@srgdamiano or @shicks, y’all seem to be my go to folks for help, so I’m @-ing you here. -
2023-08-09 at 2:18 PM #18007
@tahicksonstthomas-edu – just wondering if you tried rebooting, or tried it again.
VSC and also Platfromio regularly do updates – and sometimes just exiting and starting VSC again seems to work for me.
More recently for some reason two comport have appeared with a BlueTooth access.
You can also check what the USB enumerates as a COM port and then set it in the platformio.ini
<div>
<div>[env:mayfly]</div>
<div>upload_port = <COM#></div>
</div>
-
2023-08-09 at 2:51 PM #18008
Thanks for the reply, Neil. I tried using “upload_port” in platformio.ini and there was no change. Also restarted VSC a couple of times. Tried connecting with the Mayfly off and then on. The weird thing is that I can get simple code to load and work. But this Mayfly code, which is significantly more complex and lengthy, will compile fine, worked in the past, but now does not. As I said in my original post, the output looks like it has uploaded, but it goes way too fast and the sketch clearly isn’t loaded because I get no output on the serial monitor.
It seems like there are multiple steps in the upload process and I’m wondering if the order makes a difference?
- Mayfly off or on when you connect it to the USB port (i.e. when do you turn the Mayfly on?)
- VSC open or closed when you connect Mayfly to the port (i.e. when do you start up VSC?)
I’m flummoxed.
-
-
2023-08-09 at 3:54 PM #18009
I wonder what is the size of the code ?
From the bottom of the PIO when I build I have
RAM: [===== ] 52.2% (used 8551 bytes from 16384 bytes)
Flash: [========= ] 87.4% (used 113628 bytes from 130048 bytes)
-
2023-08-09 at 5:00 PM #18010
Well, that’s interesting. After running a compile check, I get:
RAM: [ ] 0.1% (used 9 bytes from 16384 bytes)
Flash: [ ] 0.4% (used 510 bytes from 130048 bytes)And when I do the same for “Blink” I get:
RAM: [ ] 1.6% (used 266 bytes from 16384 bytes)
Flash: [ ] 1.7% (used 2252 bytes from 130048 bytes)So, for some reason, even though it looks like it has compiled correctly and uploaded correctly, nothing is actually getting uploaded. Would the code help here? Or the platformio.ini file? Happy to share both.
-
2023-08-09 at 5:46 PM #18012
@tahicksonstthomas-edu – like as you say thats interesting, all of investigations start with that.
Probably post the code – though it looks like it is structured to not compile – eyeball the code flow from first call to setup() and subsequent calls to main() and is your section of the code isolated.
SC typically shows colour coded syntax – though .ino as a code anomaly require special enabling. IMHO the easy way is to change the .ino to .cpp
-
2023-08-09 at 6:26 PM #18013
Before I go digging through the code, I’m wondering why code would compile and run fine one week, then be “structured to not compile” the next. Do you have any idea why this might happen?
Here’s the full sketch, based off of Menu_a_la_carte:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685/** =========================================================================* @file SonarWithWifiModemLIBRARY.ino* @brief Working Maxbotix Sonar, based on simple logging example from* Anthony Aufdenkampe with Xbee wifi modem code and MMW logging.** @author Sara Geleskie Damiano <sdamiano@stroudcenter.org>* @author Anthony Aufdenkampe <aaufdenkampe@limno.com>* @author Tom Hickson <tahickson@stthomas.edu>* @copyright (c) 2017-2022 Stroud Water Research Center (SWRC)* and the EnviroDIY Development Team* This example is published under the BSD-3 license.** Build Environment: Visual Studios Code with PlatformIO* Hardware Platform: EnviroDIY Mayfly Arduino Datalogger* Firmware Library: ModularSensors v0.34.0, released 2023-03-16** DISCLAIMER:* THIS CODE IS PROVIDED "AS IS" - NO WARRANTY IS GIVEN.* ======================================================================= */// THIS CODE IS CURRENTLY WORKING ON THE MAYFLY V. 1.1// ==========================================================================// Include the libraries required for any data logger// ==========================================================================/** Start [includes] */// The Arduino library is needed for every Arduino program.#include <Arduino.h>// EnableInterrupt is used by ModularSensors for external and pin change// interrupts and must be explicitly included in the main program.#include <EnableInterrupt.h>// Include the main header for ModularSensors#include <ModularSensors.h>// For the OLED display, from switchdoclabs/SDL_Arduino_SSD1306#include <AMAdafruit_GFX.h> // For the OLED display, from switchdoclabs/SDL_Arduino_SSD1306#include <SDL_Arduino_SSD1306.h> // For the OLED display/** End [includes] */// ==========================================================================// Creating Additional Serial Ports// ==========================================================================// NeoSWSerial (https://github.com/SRGDamia1/NeoSWSerial) is the best software// serial that can be used on any pin supporting interrupts.// You can use as many instances of NeoSWSerial as you need.// Not all AVR boards are supported by NeoSWSerial./** Start [neoswserial] */#include <NeoSWSerial.h> // for the stream communicationconst int8_t neoSSerial1Rx = 7; // data in pinconst int8_t neoSSerial1Tx = -1; // data out pinNeoSWSerial neoSSerial1(neoSSerial1Rx, neoSSerial1Tx);// To use NeoSWSerial in this library, we define a function to receive data// This is just a short-cut for latervoid neoSSerial1ISR() {NeoSWSerial::rxISR(*portInputRegister(digitalPinToPort(neoSSerial1Rx)));}/** End [neoswserial] */// ==========================================================================// Assigning Serial Port Functionality// ==========================================================================/** Start [assign_ports_hw] */// If there are additional hardware Serial ports possible - use them!// We give the modem first priority and assign it to hardware serial// All of the supported processors have a hardware port available named Serial1#define modemSerial Serial1/** End [assign_ports_hw] *//** Start [assign_ports_sw] */// The Maxbotix sonar is the only sensor that communicates over a serial port// but does not use modbus// Since the Maxbotix only needs one-way communication and sends a simple text// string repeatedly, almost any software serial port will do for it.#define sonarSerial neoSSerial1 // For Neo software serial/** End [assign_ports_sw] */// ==========================================================================// Data Logging Options// ==========================================================================/** Start [logging_options] */// The name of this program fileconst char* sketchName = "SonarWithWifiModemLIBRARY.ino";// Logger ID, also becomes the prefix for the name of the data file on SD cardconst char* LoggerID = "LIBRARY_Basement_Sonar";// How frequently (in minutes) to log dataconst uint8_t loggingInterval = 1;// Your logger's timezone.const int8_t timeZone = -6; // Central Standard Time// NOTE: Daylight savings time will not be applied! Please use standard time!// Set the input and output pins for the logger// NOTE: Use -1 for pins that do not applyconst int32_t serialBaud = 115200; // Baud rate for debuggingconst int8_t greenLED = 8; // Pin for the green LEDconst int8_t redLED = 9; // Pin for the red LEDconst int8_t buttonPin = 21; // Pin for debugging mode (ie, button pin)const int8_t wakePin = 31; // MCU interrupt/alarm pin to wake from sleep// Mayfly 0.x D31 = A7 IS THIS CAUSING PROBLEM IN THE USE OF V. 1.1??// Set the wake pin to -1 if you do not want the main processor to sleep.// In a SAMD system where you are using the built-in rtc, set wakePin to 1const int8_t sdCardPwrPin = -1; // MCU SD card power pinconst int8_t sdCardSSPin = 12; // SD card chip select/slave select pinconst int8_t sensorPowerPin = 22; // MCU pin controlling main sensor power/** End [logging_options] */// ==========================================================================// Wifi/Cellular Modem Options// ==========================================================================/** Start [digi_xbee_wifi] */// For the Digi Wifi XBee (S6B)#include <modems/DigiXBeeWifi.h>// NOTE: Extra hardware and software serial ports are created in the "Settings// for Additional Serial Ports" sectionconst int32_t modemBaud = 9600; // All XBee's use 9600 by default// Modem Pins - Describe the physical pin connection of your modem to your board// NOTE: Use -1 for pins that do not apply// The pin numbers here are for a Digi XBee direcly connected to a Mayfly v1.1// I CHANGED THE Vcc PIN TO 18 HERE FROM -1 (FOR v.0.5b MCU)const int8_t modemVccPin = 18; // MCU pin controlling modem powerconst int8_t modemStatusPin = 19; // MCU pin used to read modem status// NOTE: If possible, use the <code>STATUS/SLEEP_not</code> (XBee pin 13) for status, but// the CTS pin can also be used if necessaryconst bool useCTSforStatus = true; // Flag to use the XBee <code>CTS</code> pin for statusconst int8_t modemResetPin = A5; // MCU pin connected to modem reset pin//CHANGED ResetPin HERE FOR V.1.1 BOARD FROM v.0.5b boardconst int8_t modemSleepRqPin = 23; // MCU pin used for modem sleep/wake requestconst int8_t modemLEDPin = redLED; // MCU pin connected an LED to show modem status// Network connection information for UST IoT network in OSS/OWSconst char* wifiId = "xxxxxxx"; // WiFi access point nameconst char* wifiPwd = "xxxxxxx"; // WiFi password (WPA2)// Create the modem objectDigiXBeeWifi modemXBWF(&modemSerial, modemVccPin, modemStatusPin,useCTSforStatus, modemResetPin, modemSleepRqPin, wifiId,wifiPwd);// Create an extra reference to the modem by a generic nameDigiXBeeWifi modem = modemXBWF;/** End [digi_xbee_wifi] */// ==========================================================================// Using the Processor as a Sensor// ==========================================================================/** Start [processor_stats] */#include <sensors/ProcessorStats.h>// Create the main processor chip "sensor" - for general metadataconst char* mcuBoardVersion = "v1.1"; //Only sensor using new v 1.1 Mayfly boardProcessorStats mcuBoard(mcuBoardVersion);// Create sample number, battery voltage, and free RAM variable pointers for the// processor// Variable* mcuBoardBatt = new ProcessorStats_Battery(// &mcuBoard, "12345678-abcd-1234-ef00-1234567890ab");// Variable* mcuBoardAvailableRAM = new ProcessorStats_FreeRam(// &mcuBoard, "12345678-abcd-1234-ef00-1234567890ab");// Variable* mcuBoardSampNo = new ProcessorStats_SampleNumber(// &mcuBoard, "12345678-abcd-1234-ef00-1234567890ab");/** End [processor_stats] */// ==========================================================================// Maxim DS3231 RTC (Real Time Clock)// ==========================================================================/** Start [maxim_ds3231] */#include <sensors/MaximDS3231.h>// Create a DS3231 sensor objectMaximDS3231 ds3231(1);// Create a temperature variable pointer for the DS3231// Variable* ds3231Temp =// new MaximDS3231_Temp(&ds3231, "12345678-abcd-1234-ef00-1234567890ab");/** End [maxim_ds3231] */// ==========================================================================// Settings for Additional Sensors// ==========================================================================// ==========================================================================// Maxbotix HRXL Ultrasonic Range Finder// ==========================================================================/** Start [max_botix_sonar] */#include <sensors/MaxBotixSonar.h>// A Maxbotix sonar with the trigger pin disconnect CANNOT share the serial port// A Maxbotix sonar using the trigger may be able to share but YMMV// NOTE: Extra hardware and software serial ports are created in the "Settings// for Additional Serial Ports" section// NOTE: Use -1 for any pins that don't apply or aren't being used.const int8_t SonarPower = sensorPowerPin; // Excite (power) pinconst int8_t Sonar1Trigger = -1; // Trigger pin// Trigger should be a *unique* negative number if unconnectedconst uint8_t sonar1NumberReadings = 3; // The number of readings to average// Create a MaxBotix Sonar sensor objectMaxBotixSonar sonar1(sonarSerial, SonarPower, Sonar1Trigger,sonar1NumberReadings);// Create an ultrasonic range variable pointerVariable* sonar1Range =new MaxBotixSonar_Range(&sonar1, "12345678-abcd-1234-ef00-1234567890ab");/** End [max_botix_sonar] */// ==========================================================================// Calculated Variable[s]// ==========================================================================/** Start [calculated_variables] */// Create the function to give your calculated result.// The function should take no input (void) and return a float.// You can use any named variable pointers to access values by way of// variable->getValue()// Create a function in order to have a UUID for sonar distancefloat sonarDistanceMMW(void){float sonarDistanceMeasured = sonar1Range->getValue();return sonarDistanceMeasured;}const uint8_t sonarDistanceMMWVarResolution = 3;const char *sonarDistanceMMWVarName = "distance";const char *sonarDistanceMMWVarUnit = "Millimeter";const char *sonarDistanceMMWVarCode = "sonarRangeMMW";const char *sonarDistanceMMWVarUUID = "dd90d9d9-32d9-4b80-a9c0-9202552121e8"; //Library Sump Distance UUIDVariable *sonarDistanceMMWdone = new Variable(sonarDistanceMMW, sonarDistanceMMWVarResolution, sonarDistanceMMWVarName,sonarDistanceMMWVarUnit, sonarDistanceMMWVarCode, sonarDistanceMMWVarUUID);// Create the function to calculate water level / gage height variablefloat calculateSonarGageHeight(void) {float sonarGageHeight = -9999; // Always safest to start with a bad valuefloat sonarGageHeight_mm = -9999; // Always safest to start with a bad value// float minimumRange = 300; // in millimeters; not used herefloat maximumRange = 5000; // in millimeters. Should be determined after running sensor for a while// to see what the maximum measurement is for each sump.// Relative to reference stage, where add up measured lake stage/elevation plus height of sensor above water// float sonarDistanceToZeroStage = 844 * 304.8; // Constant, in millimeters, where 304.8 mm = 1.00 ft// Where 844' is approximate elevation of the water level, in ft. above sea level.float sonarDistanceMeasured = sonar1Range->getValue();if (sonarDistanceMeasured != -9999) { // make sure all inputs are goodsonarGageHeight_mm = maximumRange - sonarDistanceMeasured;sonarGageHeight = sonarGageHeight_mm / 304.8; // to convert to feet, divide by 304.8, or divide by 1 to remain in mm.}return sonarGageHeight;}// Properties of the calculated water level / gage height variable// The number of digits after the decimal placeconst uint8_t sonarGageHeightVarResolution = 3;// This must be a value from http://vocabulary.odm2.org/variablename/const char *sonarGageHeightVarName = "gageHeight";// This must be a value from http://vocabulary.odm2.org/units/const char *sonarGageHeightVarUnit = "Foot";// A short code for the variableconst char *sonarGageHeightVarCode = "SonarGageHeight";// The (optional) universallly unique identifierconst char *sonarGageHeightVarUUID = "00ba424d-ce25-462c-80ad-a54717ba89d7"; //LIBRARY Sump gage height UUID// Create the calculated water gage height variable objects and return a variable pointer to itVariable *calculatedSonarGageHeight = new Variable(calculateSonarGageHeight, sonarGageHeightVarResolution, sonarGageHeightVarName,sonarGageHeightVarUnit, sonarGageHeightVarCode, sonarGageHeightVarUUID);// Create the function to calculate water volume in cubic feetfloat calculateSonarVolume(void) {float sonarVolume = 3.14159 * pow(2,2) * (calculatedSonarGageHeight->getValue());// In feet. Our sumps have diameter = 4 feet// Relative to reference stage, where add up measured lake stage/elevation plus height of sensor above waterreturn sonarVolume;}// Properties of the calculated water volume variable// The number of digits after the decimal placeconst uint8_t sonarVolumeResolution = 4;// This must be a value from http://vocabulary.odm2.org/variablename/const char *sonarVolumeVarName = "Volume (ft^3)";// This must be a value from http://vocabulary.odm2.org/units/const char *sonarVolumeVarUnit = "ft^3";// A short code for the variableconst char *sonarVolumeVarCode = "SonarVolume";// The (optional) universallly unique identifierconst char *sonarVolumeUUID = "bba7f366-c47f-4ad4-ae5d-1d9d818f19a3"; //Library Sump Volume UUID// Create the calculated volume of water in sump and return a variable pointer to itVariable *calculatedSonarVolume = new Variable(calculateSonarVolume, sonarVolumeResolution, sonarVolumeVarName,sonarVolumeVarUnit, sonarVolumeVarCode, sonarVolumeUUID);/** End [calculated_variables] */// ==========================================================================// Creating the Variable Array[s] and Filling with Variable Objects// NOTE: There are three different ways of creating the same variable array// and filling it with variables. Here we blend methods.// ==========================================================================/** Start [variables_create_in_array_pre_named] */Variable* variableList[] = {new ProcessorStats_SampleNumber(&mcuBoard,"12345678-abcd-1234-ef00-1234567890ab"),new ProcessorStats_FreeRam(&mcuBoard,"12345678-abcd-1234-ef00-1234567890ab"),new ProcessorStats_Battery(&mcuBoard,"12345678-abcd-1234-ef00-1234567890ab"),// new MaximDS3231_Temp(&ds3231, "12345678-abcd-1234-ef00-1234567890ab"),// Add variable using method 3, pre_namedsonar1Range,calculatedSonarGageHeight,// ... Add more variables as needed!new Modem_RSSI(&modem, "12345678-abcd-1234-ef00-1234567890ab"),new Modem_SignalPercent(&modem, "12345678-abcd-1234-ef00-1234567890ab"),// new Modem_Temp(&modem, "12345678-abcd-1234-ef00-1234567890ab"),// new Variable(calculateVariableValue, calculatedVarResolution,// calculatedVarName, calculatedVarUnit, calculatedVarCode,// calculatedVarUUID),};// Count up the number of pointers in the arrayint variableCount = sizeof(variableList) / sizeof(variableList[0]);// Create the VariableArray objectVariableArray varArray(variableCount, variableList);/** End [variables_create_in_array_pre_named] */// ==========================================================================// The Logger Object[s]// ==========================================================================/** Start [loggers] */// Create a new logger instanceLogger dataLogger(LoggerID, loggingInterval, &varArray);/** End [loggers] */// ==========================================================================// Creating Data Publisher[s]// ==========================================================================/** Start [publishers] */// A Publisher to Monitor My Watershed / EnviroDIY Data Sharing Portal// Device registration and sampling feature information can be obtained after// registration at https://monitormywatershed.org or https://data.envirodiy.orgconst char* registrationToken ="ddc1a620-a75c-458b-86b8-36f6e3b297d3"; // Device registration token for LIBRARY Basementconst char* samplingFeature ="363e0351-527b-4699-82ff-c2918e1dc09f"; // Sampling feature UUID for LIBRARY Basement// Create a data publisher for the Monitor My Watershed/EnviroDIY POST endpoint#include <publishers/EnviroDIYPublisher.h>EnviroDIYPublisher EnviroDIYPOST(dataLogger, &modem.gsmClient,registrationToken, samplingFeature);/** End [publishers] */// ==========================================================================// Working Functions// ==========================================================================/** Start [working_functions] */// Flashes the LED's on the primary boardvoid greenredflash(uint8_t numFlash = 4, uint8_t rate = 75) {for (uint8_t i = 0; i < numFlash; i++) {digitalWrite(greenLED, HIGH);digitalWrite(redLED, LOW);delay(rate);digitalWrite(greenLED, LOW);digitalWrite(redLED, HIGH);delay(rate);}digitalWrite(redLED, LOW);}// Uses the processor sensor object to read the battery voltage// NOTE: This will actually return the battery level from the previous update!float getBatteryVoltage() {if (mcuBoard.sensorValues[0] == -9999) mcuBoard.update();return mcuBoard.sensorValues[0];}/** End [working_functions] */// Set up the OLED displaySDL_Arduino_SSD1306 display(-1); // using I2C and not bothering with a reset pin// ==========================================================================// Arduino Setup Function// ==========================================================================void setup() {/** Start [setup_prints] */// Start the primary serial connectionSerial.begin(serialBaud);// Start the OLEDdisplay.begin(SSD1306_SWITCHCAPVCC, 0x3C, false);display.clearDisplay();display.setTextSize(1);display.setTextColor(WHITE);display.setCursor(0,0);// Print a start-up note to the OLED displaydisplay.println(sketchName);display.println(LoggerID);display.display();// Print a start-up note to the first serial portSerial.print(F("\n\nNow running "));Serial.print(sketchName);Serial.print(F(" on Logger "));Serial.println(LoggerID);Serial.println();Serial.print(F("Using ModularSensors Library version "));Serial.println(MODULAR_SENSORS_VERSION);Serial.print(F("TinyGSM Library version "));Serial.println(TINYGSM_VERSION);Serial.println();/** Start [setup_softserial] */// Allow interrupts for software serial#if defined SoftwareSerial_ExtInts_henableInterrupt(softSerialRx, SoftwareSerial_ExtInts::handle_interrupt,CHANGE);#endif#if defined NeoSWSerial_henableInterrupt(neoSSerial1Rx, neoSSerial1ISR, CHANGE);#endif/** End [setup_softserial] *//** Start [setup_serial_begins] */// Start the SoftwareSerial stream for the sonar; it will always be at 9600// baudsonarSerial.begin(9600);/** End [setup_serial_begins] */// Start the serial connection with the modemmodemSerial.begin(modemBaud);/** Start [setup_flashing_led] */// Set up pins for the LED'spinMode(greenLED, OUTPUT);digitalWrite(greenLED, LOW);pinMode(redLED, OUTPUT);digitalWrite(redLED, LOW);// Blink the LEDs to show the board is on and starting upgreenredflash();/** End [setup_flashing_led] *//** Start [setup_logger] */// Set the timezones for the logger/data and the RTC// Logging in the given time zoneLogger::setLoggerTimeZone(timeZone);// It is STRONGLY RECOMMENDED that you set the RTC to be in UTC (UTC+0)Logger::setRTCTimeZone(0);// Set information pinsdataLogger.setLoggerPins(wakePin, sdCardSSPin, sdCardPwrPin, buttonPin,greenLED);// Begin the loggerdataLogger.begin();/** End [setup_logger] *//** Start [setup_sensors] */Serial.println(F("Setting up sensors..."));varArray.setupSensors();/** End [setup_sensors] *//** Start [setup_file] */// Create the log file, adding the default header to it// Do this last so we have the best chance of getting the time correct and// all sensor names correctdataLogger.createLogFile(true); // true = write a new header/** End [setup_file] *//** Start [setup_sleep] */// Call the processor sleepSerial.println(F("Putting processor to sleep\n"));dataLogger.systemSleep();/** End [setup_sleep] */}// ==========================================================================// Arduino Loop Function// ==========================================================================/** Start [complex_loop] */// Use this long loop when you want to do something special// Because of the way alarms work on the RTC, it will wake the processor and// start the loop every minute exactly on the minute.// The processor may also be woken up by another interrupt or level change on a// pin - from a button or some other input.// The "if" statements in the loop determine what will happen - whether the// sensors update, testing mode starts, or it goes back to sleep.void loop() {// Reset the watchdogdataLogger.watchDogTimer.resetWatchDog();// Assuming we were woken up by the clock, check if the current time is an// even interval of the logging interval// We're only doing anything at all if the battery is above 3.4Vif (dataLogger.checkInterval() && getBatteryVoltage() > 3.4) {// Flag to notify that we're in already awake and logging a pointLogger::isLoggingNow = true;dataLogger.watchDogTimer.resetWatchDog();// Print a line to show new readingSerial.println(F("------------------------------------------"));// Turn on the LED to show we're taking a readingdataLogger.alertOn();// Power up the SD Card, but skip any waits after power updataLogger.turnOnSDcard(false);dataLogger.watchDogTimer.resetWatchDog();Serial.print("\n Range (mm): ");Serial.println(sonar1Range->getValueString());Serial.print("Gage Height (ft): ");Serial.println(calculatedSonarGageHeight->getValueString());display.print("Sonar Range (mm): ");display.println(sonar1Range->getValueString());display.print("Gage Height (ft): ");display.println(calculatedSonarGageHeight->getValueString());display.display();// Turn on the modem to let it start searching for the network// Only turn the modem on if the battery at the last interval was high// enough// NOTE: if the modemPowerUp function is not run before the// completeUpdate// function is run, the modem will not be powered and will not// return a signal strength reading.if (getBatteryVoltage() > 3.6) modem.modemPowerUp();// Do a complete update on the variable array.// This this includes powering all of the sensors, getting updated// values, and turing them back off.// NOTE: The wake function for each sensor should force sensor setup// to run if the sensor was not previously set up.varArray.completeUpdate();dataLogger.watchDogTimer.resetWatchDog();// Create a csv data record and save it to the log filedataLogger.logToSD();dataLogger.watchDogTimer.resetWatchDog();// Connect to the network// Again, we're only doing this if the battery is doing wellif (getBatteryVoltage() > 3.55) {dataLogger.watchDogTimer.resetWatchDog();if (modem.connectInternet()) {dataLogger.watchDogTimer.resetWatchDog();// Publish data to remotesSerial.println(F("Modem connected to internet."));dataLogger.publishDataToRemotes();// Sync the clock at noondataLogger.watchDogTimer.resetWatchDog();if (Logger::markedLocalEpochTime != 0 &&Logger::markedLocalEpochTime % 86400 == 43200) {Serial.println(F("Running a daily clock sync..."));dataLogger.setRTClock(modem.getNISTTime());dataLogger.watchDogTimer.resetWatchDog();modem.updateModemMetadata();dataLogger.watchDogTimer.resetWatchDog();}// Disconnect from the networkmodem.disconnectInternet();dataLogger.watchDogTimer.resetWatchDog();}// Turn the modem offmodem.modemSleepPowerDown();dataLogger.watchDogTimer.resetWatchDog();}// Cut power from the SD card - without additional housekeeping waitdataLogger.turnOffSDcard(false);dataLogger.watchDogTimer.resetWatchDog();// Turn off the LEDdataLogger.alertOff();// Print a line to show reading endedSerial.println(F("------------------------------------------\n"));// Unset flagLogger::isLoggingNow = false;}// Check if it was instead the testing interrupt that woke us upif (Logger::startTesting) {// Testing mode with output to serial monitor// Comment this line out if you want to use the OLED display// dataLogger.testingMode();// Testing mode using OLED Display// Flag to notify that we're in testing modeLogger::isTestingNow = true;// Unset the startTesting flagLogger::startTesting = false;PRINTOUT(F("------------------------------------------"));PRINTOUT(F("Entering sensor testing mode with OLED display"));delay(100); // This seems to prevent crashes, no clue why ....display.begin(SSD1306_SWITCHCAPVCC, 0x3C, false);// Power up all of the sensorsvarArray.sensorsPowerUp();// Wake up all of the sensorsvarArray.sensorsWake();// Loop through 10 measurement cycles of 3 seconds each// before exiting testing modefor (uint8_t i = 0; i <= 10; i++) {// Turn on the LED to show we're taking a readingdigitalWrite(greenLED, HIGH);dataLogger.watchDogTimer.resetWatchDog();// Update the values from all attached sensors// NOTE: NOT using complete update because we want the sensors to be// left on between iterations in testing mode.varArray.updateAllSensors();// Print the sensor result to serial portSerial.print("Number ");Serial.println(i);Serial.print("Range (mm): ");Serial.println(sonar1Range->getValueString());Serial.print("Gage Height (ft): ");Serial.println(calculatedSonarGageHeight->getValueString());// Reset the OLED displaydisplay.clearDisplay();display.setCursor(0,0);display.setTextSize(2);// Print the sensor result to OLED displaydisplay.print("Number ");display.println(i);display.print("Sonar Range (mm): ");display.println(sonar1Range->getValueString());display.print("Gage Height (ft): ");display.println(calculatedSonarGageHeight->getValueString());display.display();// Add a delay?// delay(3000);}// Put sensors to sleepvarArray.sensorsSleep();varArray.sensorsPowerDown();PRINTOUT(F("Exiting testing mode"));PRINTOUT(F("------------------------------------------"));dataLogger.watchDogTimer.resetWatchDog();// Unset testing mode flagLogger::isTestingNow = false;// SleepdataLogger.systemSleep();}// Call the processor sleepdataLogger.systemSleep();}/** End [complex_loop] */ -
2023-08-10 at 12:26 PM #18014
<quote>”Before I go digging through the code, I’m wondering why code would compile and run fine one week, then be “structured to not compile” the next. Do you have any idea why this might happen?” </quote>
So a perspective – its your code, and its your environment – so i have no idea, just throwing out a suggestion based on the data of compilation size. The whole computer is built on “sand” and layers of software, and many items can go wrong. So welcome to the wonderful world of the computer.
So I put my code under git/source control/(or plain zip my source tree) , just for when these problems occur. Basic working practice. Believe me I’ve had the weird-ist problems that come up – and then I can see the change that’s been made and why things have changed. From the snapshot I can recreate the known working program into another director – and hope it works there.
Eyeballing your code, I’m afraid nothing jumps out to me. It could be in the platformio.ini . It would seem the clue is ~ your program size reflects the nature of the program that is being downloaded.
Beats me. Perhaps duplicate your blinkme, then copy and paste the above program into the file and see the size of program it produces.
-
2023-08-10 at 3:52 PM #18015
I really want to thank you for giving me help and feedback on this. Although I can’t, for the life of me, understand what’s going on, at least someone is throwing out ideas. My code is under git/source control. I cannot see any changes that I’ve made, looking over my Github history, that could explain this. I did branch off of main to work on some other bells and whistles, but never got around to them. It just stopped compiling and loading properly I tried your cut and paste suggestion, but got the same results. I guess I’ll just keep bashing my head against the wall…
-
2023-08-10 at 6:01 PM #18016
Sometime “stuff happens” and thats why virtual machines where invented.
If you post your git link – and the project is set up right, I should be able to clone, and then open it in VSC/PIO and see if it builds.
-
2023-08-11 at 5:43 PM #18018
Here’s a link to a new public repo: https://github.com/tahickson/UST_Earth_Envt_Society
The platformio.ini file should have all you need to know in it. Should be ready to go. Thanks for giving this a try!
-
2023-08-11 at 6:18 PM #18019
great makes it easy to try it –
I cloned locally, opened the folder in VSC.
It pulled in the libs, and then I pressed the pio build button.
Advanced Memory Usage is available via “PlatformIO Home > Project Inspect”
RAM: [=== ] 34.9% (used 5724 bytes from 16384 bytes)
Flash: [======= ] 65.5% (used 85196 bytes from 130048 bytes)
Building .pio\build\mayfly\firmware.hexI’m just finished some other testing so my Mayfly was open, and I downloaded it
avrdude: 85196 bytes of flash written
Very occasionally I’ve had problems with pio getting out of sync or something. Perhaps you want to uninstall VSC. Then from the platformio page reinstall.
https://platformio.org/install/ide?install=vscode
-
2023-08-12 at 2:17 PM #18020
That definitely sounds more like what should be happening! Thanks so much for taking the time to do this, Neil. I will try to fix things on Monday when I’m back in my office and next to my sensors.
Just a funny addendum. I just created a ChapGPT account so that I could stay abreast of it in my teaching. Here is the text of my first chat:
Why won’t my sketch upload to my mayfly datalogger?
ChatGPTHey Tom! It sounds like you’re having trouble uploading your sketch to your Mayfly datalogger. There could be a few reasons for this. First, make sure you have the correct USB drivers installed for the Mayfly and that your computer recognizes it. Also, double-check your connections and ensure the datalogger is powered on.
Sometimes, issues arise due to conflicts in the sketch or with other software running on your computer. Try restarting both your computer and the datalogger, and then attempt the upload again. If the problem persists, you might want to check the Arduino IDE for any error messages that could provide more insight into what’s going wrong.
If you’re using any additional libraries in your sketch, ensure they are properly installed and compatible with your Mayfly version. Keep an eye out for any specific instructions or troubleshooting steps provided by the Mayfly community or manufacturer.
Remember, technology can be a bit finicky sometimes, but with a bit of troubleshooting, you should be able to get your sketch uploaded successfully. If you’re still having issues, don’t hesitate to reach out to fellow Mayfly users or the manufacturer’s support for more personalized assistance. Good luck, and I hope you get your datalogger up and running soon!
As for your question about my data sources, I’ve been trained on a diverse range of texts from the internet, books, articles, and other sources to provide information and generate responses. My responses are based on patterns in the data I’ve been exposed to, but I don’t have real-time access to the internet or specific external databases.
-
2023-08-12 at 3:04 PM #18021
Goodluck with tracking it down :), some cyber screw come loose.
Yes interesting to understand the basis of the technology. ChatGPT sounds coherent!! or as a “stochastic parrot”, have enough people written on the problem for it to be trained to sound coherent :).
A friend said they found it helps debug xls macros!!
Like handling a “knife”, we might need to figure out how to use the “cutting edge”. Here is an article on the roots of the technology
Technology
How does ChatGPT work and do AI-powered chatbots “think” like us?
The large language models behind the new chatbots are trained to predict which words are most likely to appear together – but “emergent abilities” suggest they might be doing more than that25 July 2023 (newScientist)
By Edd Gent
2R59MEN ChatGPT, chatbots and AI
Illustronaut/AlamyThe current whirlwind of interest in artificial intelligence is largely down to the sudden arrival of a new generation of AI-powered chatbots capable of startlingly human-like text-based conversations. The big change came last year, when OpenAI released ChatGPT. Overnight, millions gained access to an AI producing responses that are so uncannily fluent that it has been hard not to wonder if this heralds a turning point of some sort.
There has been no shortage of hype. Microsoft researchers given early access to GPT4, the latest version of the system behind ChatGPT, argued that it has already demonstrated “sparks” of the long-sought machine version of human intellectual ability known as artificial general intelligence (AGI). One Google engineer even went so far as to claim that one of the company’s AIs, known as LaMDA, was sentient. The naysayers, meanwhile, insist that these AIs are nowhere near as impressive as they seem.
All of which can make it hard to know quite what you should make of the new AI chatbots. Thankfully, things quickly become clearer when you get to grips with how they work and, with that in mind, the extent to which they “think” like us.
At the heart of all these chatbots is a large language model (LLM) – a statistical model, or a mathematical representation of data, that is designed to make predictions about which words are likely to appear together.
LLMs are created by feeding huge amounts of text to a class of algorithms called deep neural networks, which are loosely inspired by the brain. The models learn complex linguistic patterns by playing a simple game: the algorithm takes a passage of text, randomly masks out some words and then tries to fill in the gaps. They are, in short, trained to predict the next word. And by repeating the process over and over, they can build up sophisticated models of how language works, says Mirella Lapata at the University of Edinburgh, UK.
Recent breakthroughs are largely down to a new type of neural network invented in 2017 called a “transformer”, which can process data far more efficiently than previous approaches. This made it possible to train much larger models on vast tracts of text scraped from the internet. Transformer-based systems are also much better at understanding context, says Lapata. Whereas older versions could only consider a few words either side of the missing one, transformers can process much longer strings of text, meaning they can tease out more complex and subtle linguistic relationships.
What turns otherwise unwieldy statistical models into smooth-talking chatbots, meanwhile, is humans rating the output of AIs on criteria like helpfulness and fluency. This data is then used to train a separate “preference model” that filters an LLM’s output. Put this together and you get what we have today, namely a text-based, computerised conversational partner often indistinguishable from a human. The fact that this was achieved using a premise as simple as next-word prediction caught a lot of people by surprise, says Tal Linzen at New York University.
But it is important to remember that the way these AIs operate almost certainly isn’t the way human cognitive processes work. “They learn in such a fundamentally different way from people that it makes it very improbable [that] they ‘think’ the same way people do,” says Linzen.
Here, the mistakes chatbots make are instructive. They are prone to confidently trumpeting falsehoods as facts, something often referred to as “hallucination”, because their output is entirely statistical. “It doesn’t do fact-checking,” says Lapata. “It just generates output that is likely or plausible, but not necessarily true.”
This has led some commentators to disparage chatbots as “stochastic parrots” and their output as nothing more than “a blurry JPEG of the web”. The gist of these jibes is that the new LLMs aren’t as impressive as they first appear – that what they do is merely the imperfect memorisation of training data cleverly stitched back together to give the false impression of understanding.
Emergent abilities
And yet there are some indications that LLMs might be doing more than just regurgitating training data, says Raphaël Millière at Columbia University in New York. Recent research suggests that, after training for long enough, models can develop more general rules that give them new skills. “You get this transition from memorisation to the formation of circuits inside the [neural] network that will be implementing certain algorithms or certain rules to solve the tasks,” he says.This may help to explain why, as LLMs increase in size, they often experience sudden jumps in performance on certain problems, says Millière. This phenomenon has been referred to as “emergence” and has led to speculation about what other unexpected capabilities AI could develop.
It is important not to get carried away. “This term is very seductive,” says Millière. “It evokes things like the models suddenly becoming self-aware, or things like that. That’s not what we’re talking about.”
Even so, Millière thinks there is a “rich middle ground” between the naysayers and hype merchants. While these chatbots are far from replicating human cognition, in some narrow areas, they may not be so different from us. Digging into these similarities could not only advance AI, he says, but also sharpen our understanding of our own cognitive capabilities.
This story is part of a series in which we explore the most pressing questions about artificial intelligence. Read the other articles below
What generative AI really means for the economy, jobs and education | Forget human extinction – these are the real risks posed by AI today | How to use AI to make your life simpler, cheaper and more productive | The biggest scientific challenges that AI is already helping to crack | Can AI ever become conscious and how would we know if that happens? -
2023-08-12 at 3:14 PM #18022
So good to play around with it, I asked bard.google.com a question that doesn’t have a lot written about it ..
“What is the quiescent power consumption of the Bristlemouth hardware”
AND it sounds coherent – however its “hallucinating” as not a google project. The 10milliwatts its quoting is the active transmission per Mhz.
I’ve got an open question to the designers .. (https://www.bristlemouth.org/ https://bristlemouth.discourse.group/t/what-is-the-expected-power-profile-and-quiescent-current/65)
Bard Answer:
<p data-sourcepos=”1:1-1:316″>The quiescent power consumption of the Bristlemouth hardware is 10 milliwatts (mW). This means that the hardware consumes very little power when it is not actively processing data. This makes it ideal for applications where power consumption is a critical factor, such as battery-powered devices or embedded systems.</p>
<p data-sourcepos=”3:1-3:270″>The Bristlemouth hardware is a neural network accelerator developed by Google AI. It is designed to be highly energy efficient, while still providing high performance. The quiescent power consumption of 10 mW is achieved through a number of design techniques, including:</p><ul data-sourcepos=”5:1-8:0″>
<li data-sourcepos=”5:1-5:29″>Using a low-power processor
<li data-sourcepos=”6:1-6:24″>Using low-power memory
<li data-sourcepos=”7:1-8:0″>Using a power-gating mechanism to turn off components when they are not in use<p data-sourcepos=”9:1-9:220″>The Bristlemouth hardware is a significant improvement over previous generations of neural network accelerators in terms of power efficiency. This makes it a valuable tool for developing energy-efficient AI applications.</p>
-
2023-08-14 at 11:39 AM #18023
<h1>Partially solved!</h1>
I may have found part of the problem, thanks to you. I had to create a new repo in order to share my code with you. When I open that new repo in VSC from Github desktop it compiles as you’ve described. I was starting to have a hunch that the problem was that I had branched from main to add some additional functionality and I thought that I could just upload from that branch. However, the branched code doesn’t compile or upload as described above. When I revert to main on Github desktop and open the code, it compiles and uploads just fine. You learn something new every day (or week or month, in my case).So, this worked for one of the sketches. But when I tried this on a second sketch that uses a different Mayfly, I get the old behavior. I’ll keep trying!
-
2023-08-14 at 3:06 PM #18024
Hey glad to have helped!!. Whew.!
Its a challenge sometime to figure out what the foundations are and build off them. I’ve had to do that before, start with a known should be working, and then slowly add to it to find out what came adrift. I often use Meld Merge to compare the base directories separately from PIO. There is a gitkraken plugin of PIO to visualize the branches – however I get lost quickly.
So your process of rebuilding from a known source is teaching moment of the challenges of source management. The next challenge is traceability – and its mostly the school of hard knocks. Sara is doing an amazing job of fixing lib versions for the main release.
You have the Mayfly version built in nicely to you platformio.ini- EnviroDIY_ModularSensors@=0.34.0
Can you imagine having your code all working, and distributed being used, and then coming back to make a modification – only to find its lost – you can’t trace what your release was. Several professional level stories of that happening – and hence why Microsoft bought github for gizzilion$
https://meldmerge.org/ though I ‘m currently on an early version 3.18.3 https://download.gnome.org/binaries/win32/meld/ as some lost functionality in later releases
-
2023-08-14 at 4:00 PM #18025
Alright, I have no idea if this will help or not, but I think it’s important that I get this down for completeness.
- If I open the public repo that I shared above in VSC from Github Desktop, then copy the sketch into it that I need to load, it seems to compile and upload. So, as of right now, I have my sketches loaded onto my boards and they are cranking away.
- However, I don’t want to share my passwords and such in a public repo. So, I duplicated the public repo above following the guidelines here. When I open that repo and try to compile or upload the very same sketches in the duplicate, private repo, I get the same problem of them not compiling and uploading, as above.
I tried going back in time on Platformio to see if the new version of it was causing this problem, but that’s not it. There seems to be something going on between VSC and Github. Changing the private repo to public doesn’t change the bad behavior.
-
2023-08-14 at 6:53 PM #18028
Well you are now into working deployment practice’s, beyond programming,
So how about simplifying (I think you’re process is getting complicated . IHMO all the guideline haven’t identified what happens when you actually have a successful program to deploy .)
Seems the question is for a successful working Mayfly logger program ….. and how to scale it to the field.
…. you have a very good point
~~ grin ~~
Seems to me a really SIMPLE way of solving it is to put the UUIDs in an include file – and then manage the include file separately so they don’t go to github. Say “ms_cfg_uuids.h” This works if its you (and any similar programmers/colleagues) are building and deploying to the field and you can agree on labeling and where to keep the ms_cfg_uuids.h
IMHO – this is a beta development scheme. For each Mayfly it still has to be be compiled with each separate ms_cfg_uuuds.h and then downloaded to each Mayfly, and tracked on a Mayfly basis. IHMO2 this shows a weakness in EnviroDIY working practises , how to test a program to prove its successful.
If you want to deploy a number (10->??) or so loggers all the same, … what then … Deploying a number of Mayfly loggers becomes a bit more of a production line.
What I do, in my fork, (and its a big step of functionality) is put the UUIDs in a file ms_cfg.txt and then put it on the uSD. This is ideal for situations where colleagues are not programmers, but can configure a system through a built .hex and then uniquely configure the system with ms_cfg.txt
The program can be tested, and with the captured .HEX file easily deployed in multiple numbers.
Its also easy to upgrade, as its the uSD that is the key to connecting it to MMW – not the program.
I wrote about it here https://www.envirodiy.org/geographical-scaling-modularsensors/
I also write about other features that I think are missing from the mainline https://github.com/neilh10/ModularSensors
hope that is helpful 🙂
-
2023-08-15 at 11:42 AM #18029
I think I agree with you about the complexity of deploying multiple sensor packages, each with different UUIDs. However, I don’t think that is what’s screwing me up here. As of now, I simply can’t get my sketches to reliably upload to the boards. I honestly don’t think that the compile and upload process is even getting to a place in my code where UUIDs are even called. Something is compiling and uploading, but it’s only a fraction of the size of my code and it does nothing. When I first coded it, no problem. Now, only problems. So my fear is that I will deploy these sensors, then in a couple of weeks I will need to update the code (I need to acquire a couple week’s worth of data to find the max sonar distance) and I won’t be able to do it in place because the code won’t upload. The really frustrating part of this is the fact that no single “fix” has worked. Something works once, then not again.
-
2023-08-15 at 3:24 PM #18031
It seems to me its a working practice’s issue, repeatability and traceability- not a programming issue. From a distance, seems like you should be able to see the code in the directory that you are building – however you do have a unique directory structure, and if opening HicksonDeployments.code-workspace – maybe its mispointed. I open “folders”.
For the working directory that compiles and downloads, my suggestion was by putting the UUIDs in a separate file ms_cfg_uuids.h -you can have the example non real UUIDs that get pushed to git.
On building your managed target system, you drop in the unqieu ms_cfg_uuds.h into the directory and then compile it.
That way there isn’t any messing around with the actual source code, and whats on a branch.
I would suggest adding a “GEOGRAPHICAL_ID” in your ms_cfg_uuids.h so the UUIDs compiled are visible, traceable and debugable.
On startup, my systems identify parts so I can manage the code – the code source, the software name, compile and then the target .
So from my debug logs, I’m currently trying to integrate the SIM7080 and was doing it previously with WiFi ESP32-wroom, I can follow what works and doesn’t
[2023-08-12 09:52:20.083] —Boot(0) Sw Build: a\src\tu_xx02.cpp Aug 12 2023 09:50:19 b’neilh20′
[2023-08-12 09:52:20.146] Sw Name: LT500/Modbus TO MMW LTE SIM7080
[2023-08-12 09:52:20.146] ModularSensors version 0.34.1-abd
[2023-08-12 09:52:20.146] TinyGSM Library version 0.11.6-aab[2023-08-12 09:52:20.225] Board: Assume Mayfly 1.1A
[2023-08-12 09:52:22.360] GEOGRAPHICAL_ID:”230723 TU-RCtest07 simRiverX Monitor”
earlier I was working on
[2023-08-04 18:19:16.580] —Boot(0) Sw Build: a\src\tu_xx02.cpp Aug 4 2023 18:14:40 b’neilh20′
[2023-08-04 18:19:16.632] Sw Name: LT500/Modbus TO MMW ESP32-wroom
[2023-08-04 18:19:16.632] ModularSensors version 0.34.1-abd
[2023-08-04 18:19:16.632] TinyGSM Library version 0.11.6-aab[2023-08-04 18:19:16.719] Board: Assume Mayfly 1.1A
[2023-08-04 18:19:18.847] GEOGRAPHICAL_ID:”230723 TU-RCtest07 simRiverX Monitor”
-
2023-08-16 at 1:03 PM #18034
I think that the directory structure could be the culprit. The way that I have been able to reliably get this work is the following:
- Create a new Platformio project.
- Create an identically-named folder in that project in which to put my code.
- Create an identically-named .ino file in that folder for the sketch I need to upload.
- Use the Compare files functionality in VSC to move all of my old code into those new files.
- Compile and upload
So I’m basically re-making the project in platformio and that seems to work.
-
-
AuthorPosts
- You must be logged in to reply to this topic.