BriComp
Well-known member
I am trying to use the Snooze utility, waking up from DeepSleep on a pin going LOW and on a timer.
The pin going LOW indicates that there is a message being collected by UART radio.
The pin (AUX) goes LOW 5ms before the radio starts putting the data on it's TX pin, teensy's RX pin.
Below is a logic analyser trace. (£10 from Hobby Components- fantastic value for money )
The teensy puts pin 13 (led) HIGH as soon as Teensy wakes up. Looking at the trace indicates
that it takes Teensy 20ms to Wakeup. Is this to be expected...seems very long.
Unfortunately the information being sent to Teensy on Serial1 is long gone by the time that Teensy wakes up.
I need it to wake up and be in a state to receive Serial1 data in <=5ms. Is that unreasonable?
I have included the code below. It's rather long but I don't know how to cut it down much more
and still be able to show the problem I am having. Bye the way I am using a Teensy 4.0.
CLICK on Logic Analyser Trace to Expand.
The pin going LOW indicates that there is a message being collected by UART radio.
The pin (AUX) goes LOW 5ms before the radio starts putting the data on it's TX pin, teensy's RX pin.
Below is a logic analyser trace. (£10 from Hobby Components- fantastic value for money )
The teensy puts pin 13 (led) HIGH as soon as Teensy wakes up. Looking at the trace indicates
that it takes Teensy 20ms to Wakeup. Is this to be expected...seems very long.
Unfortunately the information being sent to Teensy on Serial1 is long gone by the time that Teensy wakes up.
I need it to wake up and be in a state to receive Serial1 data in <=5ms. Is that unreasonable?
I have included the code below. It's rather long but I don't know how to cut it down much more
and still be able to show the problem I am having. Bye the way I am using a Teensy 4.0.
CLICK on Logic Analyser Trace to Expand.
Code:
/*
* LoRa E32-TTL-100
* Receive fixed transmission message on channel.
* https://www.mischianti.org
*
* E32-TTL-100----- Arduino UNO or esp8266
* M0 ----- 3.3v (To config) GND (To send) 2 (To dinamically manage)
* M1 ----- 3.3v (To config) GND (To send) 3 (To dinamically manage)
* TX ----- RX PIN 1 (PullUP)
* RX ----- TX PIN 0 (PullUP & Voltage divider)
* AUX ----- Connected (4 if you connect)
* VCC ----- 3.3v/5v
* GND ----- GND
*
*/
#include <TimeLib.h>
#include "Arduino.h"
//#include "LoRa_E32.h"
#include "EBYTE.h"
#include <Wire.h>
#include "Adafruit_MCP9808.h"
// Load Snooze drivers
#include <Snooze.h>
SnoozeDigital snoozeDigital;
SnoozeTimer snoozeTimer;
SnoozeUSBSerial SerialUsb;
#if defined(__IMXRT1062__)
SnoozeBlock config_teensy40(SerialUsb, snoozeDigital, snoozeTimer ); //alarm);
#elif defined(__MK64FX512__)
#elif defined(__MK66FX1M0__)
SnoozeBlock config_teensy36(SerialUsb, snoozeDigital, snoozeTimer);
SnoozeBlock config_teensy35(SerialUsb, snoozeDigital, snoozeTimer);
#elif defined(__MK20DX256__)
SnoozeBlock config_teensy32(SerialUsb, snoozeDigital, snoozeTimer);
#elif defined(__MK20DX128__)
SnoozeBlock config_teensy30(SerialUsb, snoozeDigital, snoozeTimer);
#elif defined(__MKL26Z64__)
SnoozeBlock config_teensyLC(SerialUsb, snoozeDigital, snoozeTimer);
#endif
#define SerialUsb Serial
/*------------------------------------------------------------------------
* Parameter Setup
-------------------------------------------------------------------------*/
// Oled 128X64 Display
// Radio Parameters
#define PIN_M0 2
#define PIN_M1 3
#define PIN_AX 4
#define auxPin PIN_AX
#define FREQUENCY_868
MODE_TYPE radioMode;
#define RadioSerial Serial1
EBYTE Radio(&RadioSerial, PIN_M0, PIN_M1, PIN_AX);
//LoRa_E32 radio(&radioSerial, PIN_AX, PIN_M0, PIN_M1);
/*------------------------------------------------------------------------
* Radio Addresses etc
--------------------------------------------------------------------------*/
const byte cprlbHomeADRH = 0x00;
const byte cprlbHomeADRL = 0x03;
const byte cprlbHomeCHAN = 0x04;
const byte masterADRH = 0x00;
const byte masterADRL = 0x01;
const byte masterCHAN = 0x04;
const bool asleep = true;
const bool awake = false;
#pragma pack(push,1)
typedef struct addrType{
byte H;
byte L;
byte Chan;
} addrType;
addrType addr;
/***************************************************************************
* SLAVE Data Types *
***************************************************************************/
typedef struct SlaveToMasterReplyType{
byte replyFrom;
byte replyWhat;
uint16_t data;
} SlaveToMasterReplyType;
SlaveToMasterReplyType slaveToMasterReply;
const int sizeOfSlaveToMasterReplyType = sizeof(SlaveToMasterReplyType);
typedef union SlaveToMasterReplyUnion{
SlaveToMasterReplyType data;
uint8_t buf[sizeOfSlaveToMasterReplyType];
} SlaveToMasterReplyUnion;
SlaveToMasterReplyUnion slaveToMasterReceive;
typedef struct SlaveToMasterTransmitDataType{
addrType addr;
SlaveToMasterReplyType message;
} SlaveToMasterTransmitDataType;
const int sizeOfSlaveToMasterTransmitDataType = sizeof(SlaveToMasterTransmitDataType);
typedef union SlaveToMasterTransmitReplyUnion{
SlaveToMasterTransmitDataType data;
uint8_t buf[sizeOfSlaveToMasterTransmitDataType];
} SlaveToMasterTransmitReplyUnion; // slaveToMasterData;
SlaveToMasterTransmitReplyUnion slaveToMasterTransmit;
/***************************************************************************
* MASTER Data Types *
***************************************************************************/
typedef struct MasterToSlaveCommandType{
byte command;
unsigned long time;
uint16_t temperature;
} MasterToSlaveCommandType;
MasterToSlaveCommandType masterToSlaveCommand;
const int sizeOfMasterToSlaveCommandType = sizeof(MasterToSlaveCommandType);
typedef union MasterToSlaveCommandUnion{
MasterToSlaveCommandType data;
uint8_t buf[sizeOfMasterToSlaveCommandType];
} MasterToSlaveCommandUnion;
MasterToSlaveCommandUnion masterToSlaveReceive;
typedef struct MasterToSlaveTransmitDataType{
addrType addr;
MasterToSlaveCommandType message;
} MasterToSlaveTransmitDataType;
const int sizeOfMasterToSlaveTransmitDataType = sizeof(MasterToSlaveTransmitDataType);
typedef union MasterToSlaveTransmitUnion{
MasterToSlaveTransmitDataType data;
uint8_t buf[sizeOfMasterToSlaveTransmitDataType];
} MasterToSlaveTransmitUnion;
MasterToSlaveTransmitUnion masterToSlaveTransmit;
#pragma pack(pop)
unsigned long waitTilRadioTxBufferEmpty; // if (Use millis() >= waitTilRadioTxBufferEmpty) so as not to overload radio comms
/*------------------------------------------------------------------------
* Setup Radio - function is called once at startup of the sketch
-------------------------------------------------------------------------*/
void SetupRadio( addrType a, byte wakeUp, /*uint8_t pwrStatus, */bool sleep ){
RadioSerial.begin(9600);
Radio.init();
Radio.SetAddressH(0); //a.H ); //Set up Satallite/Master Home Address and Channel Data
Radio.SetAddressL(3); // a.L );
Radio.SetChannel(4); // a.Chan );
Radio.SetAirDataRate( ADR_2400 );
Radio.SetUARTBaudRate( UDR_9600 );
Radio.SetParityBit( PB_8N1 );
// SET OPTIONS
Radio.SetWORTIming( wakeUp ); //OPT_WAKEUP250;
Radio.SetTransmissionMode( OPT_FixedModeENABLE );
Radio.SetPullupMode( OPT_IOOPENDRAIN );
Radio.SetFECMode( OPT_FECENABLE );
Radio.SetTransmitPower( OPT_TP20 );
Radio.SaveParameters(PERMANENT);
if (sleep) {
radioMode = MODE_POWERDOWN;
}
else
{
radioMode = MODE_WAKEUP; // Should only send when they are asleep though there may mbe times when comms take place after they are awake;radio.setMode(MODE_0_NORMAL); or should it be
};
Radio.SetMode(radioMode);
ClearRadioSerialInputBuffer();
} //SetupRasio
/*------------------------------------------------------------------------
* ***********************************************************************
* SLAVE ROUTINES *
* ***********************************************************************
-------------------------------------------------------------------------*/
/*------------------------------------------------------------------------
* Setup Snooze - send to sleep to save current
-------------------------------------------------------------------------*/
void SetupSnooze(){
#if defined(__IMXRT1062__)
snoozeTimer.setTimer(60);// seconds
#else
snoozeTimer.setTimer(60000);// milliseconds
#endif
snoozeDigital.pinMode(PIN_AX, INPUT_PULLUP, LOW);//pin, mode, type
}; // SetupSnooze
/*------------------------------------------------------------------------
* SLAVE: System Setup - for Slave
-------------------------------------------------------------------------*/
void setup() // SLAVE
{
int led = 13;
pinMode(led, OUTPUT);
digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
SetupSnooze();
SetupRadio(addr, OPT_WAKEUP250, asleep);
} // SLAVE setup()
/*------------------------------------------------------------------------
* SLAVE: loop - the main program loop - for Slave
-------------------------------------------------------------------------*/
void loop() // SLAVE
{
char str[20];
int who;
int n;
/********************************************************
feed the sleep function its wakeup parameters. Then go
to deepSleep.
********************************************************/
delay(1000);
digitalWrite(13,LOW);
SerialUsb.println("I am about to go to sleep");
SerialUsb.flush(); //
delay(500);
#if defined(__IMXRT1062__)
who = Snooze.deepSleep( config_teensy40 );// return module that woke processor
#elif defined(__MK66FX1M0__)
who = Snooze.deepSleep( config_teensy36 );// return module that woke processor
#elif defined(__MK64FX512__)
who = Snooze.deepSleep( config_teensy35 );// return module that woke processor
#elif defined(__MK20DX256__)
who = Snooze.deepSleep( config_teensy32 );// return module that woke processor
#elif defined(__MK20DX128__)
who = Snooze.deepSleep( config_teensy30 );// return module that woke processor
#elif defined(__MKL26Z64__)
who = Snooze.deepSleep( config_teensyLC );// return module that woke processor
#endif
unsigned long wakeupTime0 = millis();
if (!RadioSerial)
Serial1.begin(9600);
wakeupTime0 = millis() - wakeupTime0;
if (who== PIN_AX) {
if (AuxHigh()) digitalWrite(13,HIGH);
if (RadioSerial.available() >= 1){
n=RadioSerial.available();
RadioSerial.readBytes(masterToSlaveReceive.buf, sizeOfMasterToSlaveCommandType );
masterToSlaveCommand = masterToSlaveReceive.data;
} //(radio.available() > 1)
}
unsigned long wakeUpTime = millis() +8000;
while ( !SerialUsb && (millis() < wakeUpTime)){
};
unsigned long SerialUsbUpTime = millis();
SerialUsb.print( "Time to wake up RadioSerial "); SerialUsb.println( wakeupTime0 );
SerialUsb.print( "Time to wake up SerialUsb "); SerialUsb.println( SerialUsbUpTime - wakeUpTime - 8000 );
SerialUsb.print("I have woken up. Who="); SerialUsb.println(who);
} // SLAVE loop()
void ClearRadioSerialInputBuffer(){
byte b;
while(RadioSerial.available()) {
b = RadioSerial.read();
}
}; // ClearRadioSerialInputBuffer
bool AuxLow(){
return (digitalRead(auxPin)==LOW);
};
bool AuxHigh(){
return (digitalRead(auxPin)==HIGH);
};
Last edited: