Teensy 4.0 Sleep with CAN wakeup

So much for proof read several times lol, I added the missing loop code in the previous post.

I would say your fix is working, I’m not sure why I have to have more than one CAN device on the bus for that bus to wake up, seems a bit odd but in my vehicle each bus will have multiple modules so it’s not a big deal but could still be a bug in the code or even in the flexCAN code.
 
I do not have a separate pin for wake up, each CAN RX pin is setup to be the wake up source.
In other words, hardware wise, what's needed to sleep the Teensy and wake the Teensy over CAN is the following if we only use one network.
Where STB is an output pin from the Teensy to tell the transciever to go to sleep (HIGH/LOW). The transciever then wakes the Teensy when there's activity on RX because the Teensy interrupt listens for change on that pin. And with those things said the circle closed?

Code:
#define CAN1_STB 7      // Transceiver Standby Pin
#define CAN1_RX 23      // Transceiver RX Pin
 
I’m not sure why I have to have more than one CAN device on the bus for that bus to wake up
Well with only one active node the packet's don't get ACK'd and the single node will eventully fall into passive error mode if it sends packets regularly?
 
In other words, hardware wise, what's needed to sleep the Teensy and wake the Teensy over CAN is the following if we only use one network.
Where STB is an output pin from the Teensy to tell the transciever to go to sleep (HIGH/LOW). The transciever then wakes the Teensy when there's activity on RX because the Teensy interrupt listens for change on that pin. And with those things said the circle closed?

Code:
#define CAN1_STB 7      // Transceiver Standby Pin
#define CAN1_RX 23      // Transceiver RX Pin
Yes that is correct if your only using one CAN module.
Well with only one active node the packet's don't get ACK'd and the single node will eventully fall into passive error mode if it sends packets regularly?
The part I don’t understand is that the teensy interrupt isn’t looking for a valid CAN frame, it’s just looking for a falling edge on the RX pin which it gets many from a single CAN frame but won’t wake unless another module is on the bus also. I have a CAN transmitter that will relentlessly send the same frame till it properly transmits and that can’t wake the teensy unless another module is attached to the network. Doesn’t make any sense to me as it should wake even on frame errors. I think there is still some issues with the snooze library but it’s way beyond my capabilities to fix at my experience level.
 
Yes that is correct if your only using one CAN module.

The part I don’t understand is that the teensy interrupt isn’t looking for a valid CAN frame, it’s just looking for a falling edge on the RX pin which it gets many from a single CAN frame but won’t wake unless another module is on the bus also. I have a CAN transmitter that will relentlessly send the same frame till it properly transmits and that can’t wake the teensy unless another module is attached to the network. Doesn’t make any sense to me as it should wake even on frame errors. I think there is still some issues with the snooze library but it’s way beyond my capabilities to fix at my experience level.
This is a hunch but maybe the strength from one transciever isn't enough. Not enough power? But when two is sending there's more "signal strength".
 
Perhaps the bus isn't terminated properly (120 ohms at each end) if there's only one transceiver attached?
 
Yes that is correct if your only using one CAN module.

The part I don’t understand is that the teensy interrupt isn’t looking for a valid CAN frame, it’s just looking for a falling edge on the RX pin which it gets many from a single CAN frame but won’t wake unless another module is on the bus also. I have a CAN transmitter that will relentlessly send the same frame till it properly transmits and that can’t wake the teensy unless another module is attached to the network. Doesn’t make any sense to me as it should wake even on frame errors. I think there is still some issues with the snooze library but it’s way beyond my capabilities to fix at my experience level.
The components that’s supposed to send the wake up signal is the transciver, as it will pull the RDX pin LOW when it detects a bus wakeup sequence, and that only.
Teensy does not have this capability built into the controller.
Sending a std frame won’t trigger that as far as I know.

But, there seems to be an option to set some bits in the frame to signal the wakeup sequence:
 
I have been looking for any success to see if any one has gotten can wake up and sleep working and doesn't look like it?
I am in the same boat and want to draw less power when can network is sleeping. I have two teensy 4.0 in my truck as have two man in middle networks running powered up 24/7.
I have set the CPU clock to 150MHZ.
Any of you guys got a working solution as these modules are on constant Batt power.
Cheers
 
I have the teensy successfully going to sleep and waking up on all 3 CAN buses, sleep current isn’t great at about 10mA but way better than 100mA at idle, I do have to have at least 2 other CAN nodes on each bus for it to wake properly from that bus.
 
This is great !! Are you able to help or show me how you did this by chance ?
Any help is Always appreciated .
I’m using the flex can T4 library as well.
Thanks
 
Last edited:
This is great !! Are you able to help or show me how you did this by chance ?
Any help is Always appreciated .
I’m using the flex can T4 library as well.
Thanks
Here is the basic code I’m using.
Code:
#include <FlexCAN_T4.h>
#include <Snooze.h>

//************************************
#define CAN1_STB 7      // Transceiver Standby (Enable) Pin
#define CAN2_STB 12     // Transceiver Standby (Enable) Pin
#define CAN3_STB 14     // Transceiver Standby (Enable) Pin
#define CAN1_RX 23      // CAN RX Pin
#define CAN2_RX 0       // CAN RX Pin
#define CAN3_RX 30      // CAN RX Pin

SnoozeDigital digital;
SnoozeUSBSerial usb;
SnoozeBlock config(usb, digital);

FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> HS1_CAN;
FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> HS2_CAN;
FlexCAN_T4<CAN3, RX_SIZE_256, TX_SIZE_16> HS3_CAN;

/***********Timers************/
  elapsedMillis keep_awake;

/**********Variables**********/
// none at the moment

void CAN_INT(){
  // Setup HS1_CAN (CAN1)
  HS1_CAN.begin();
  HS1_CAN.setClock(CLK_60MHz);
  HS1_CAN.setBaudRate(500000);
  HS1_CAN.enableFIFO();
  HS1_CAN.enableFIFOInterrupt();
  HS1_CAN.onReceive(HS1_Receive);
 
  // Setup HS2_CAN (CAN2)
  HS2_CAN.begin();
  HS2_CAN.setClock(CLK_60MHz);
  HS2_CAN.setBaudRate(500000);
  HS2_CAN.enableFIFO();
  HS2_CAN.enableFIFOInterrupt();
  HS2_CAN.onReceive(HS2_Receive);

  // Setup HS3_CAN (CAN3)
  HS3_CAN.begin();
  HS3_CAN.setClock(CLK_60MHz);
  HS3_CAN.setBaudRate(500000);
  HS3_CAN.enableFIFO();
  HS3_CAN.enableFIFOInterrupt();
  HS3_CAN.onReceive(HS3_Receive);
  }

void TRX(uint8_t mode){
  digitalWrite(CAN1_STB, mode);
  digitalWrite(CAN2_STB, mode);
  digitalWrite(CAN3_STB, mode);
  }

void setup(){
  pinMode(CAN1_STB, OUTPUT);
  pinMode(CAN2_STB, OUTPUT);
  pinMode(CAN3_STB, OUTPUT);
  digital.pinMode(CAN1_RX, INPUT, FALLING); // Set wakeup pin
  digital.pinMode(CAN2_RX, INPUT, FALLING); // Set wakeup pin
  digital.pinMode(CAN3_RX, INPUT, FALLING); // Set wakeup pin
  CAN_INT();
  }

void HS1_Receive( const CAN_message_t &msg){
  keep_awake = 0;
  switch(msg.id){
    case 0x123:
      // Do something
      break;

    case 0x456:
      // Do something
      break;

    }// End of switch statement
  }// End of HS1-CAN Receive

void HS2_Receive(const CAN_message_t &msg){
  keep_awake = 0;
  switch(msg.id){
    case 0x123:
      // Do something
      break;

    case 0x456:
      // Do something
      break; 
  
    }// End of switch statement
  }// End of HS2-CAN Receive

void HS3_Receive( const CAN_message_t &msg){
  keep_awake = 0;
  switch(msg.id){
    case 0x123:
      // Do something
      break;

    case 0x456:
      // Do something
      break;

    }// End of switch statement
  }// End of HS3-CAN Receive

void loop(){
  if(keep_awake  >= 60000){ // If 60s has elapsed with no CAN activity, go to sleep
    TRX(HIGH);                // Put Transceivers In Standby Mode
    Snooze.deepSleep(config); // Put System To Sleep
    keep_awake = 0;           // Reset keep_awake on wake up
    TRX(LOW);                 // Put Transceivers In Active Mode
    CAN_INT();                // Re-initialize CAN modules
    }

  HS1_CAN.events();
  HS2_CAN.events();
  HS3_CAN.events();
  }//End of Loop
 
Last edited:
Back
Top