mehmet
mehmet

Reputation: 1598

Why TWAI (CANBUS) library not working for ESP32?

enter image description here

I have created a simple circuit cor CANBUS (TWAI) communication between Arduino NANO and ESP32 Dev kit. At first I was using this library and my circuit works fine. this is te serial monitors:

enter image description here

But for ESP32 if I want to use TWAI library it is not responding and not working

this is TWAI codes:

#include <Arduino.h>
#include <driver/twai.h>

// Define the TWAI GPIO pins for ESP32 Dev Kit
const gpio_num_t RX_PIN = GPIO_NUM_4;  // Change as needed
const gpio_num_t TX_PIN = GPIO_NUM_5;  // Change as needed

// Define the TWAI configuration
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(TX_PIN, RX_PIN, TWAI_MODE_NORMAL);
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();

void setup() {
  Serial.begin(115200);
  while (!Serial); // Wait for the serial port to connect
  delay(2000);

  Serial.println("Initializing TWAI (CAN) Receiver...");

  // Install TWAI driver
  if (twai_driver_install(&g_config, &t_config, &f_config) != ESP_OK) {
    Serial.println("Failed to install TWAI driver");
    return;
  }

  // Start the TWAI driver
  if (twai_start() != ESP_OK) {
    Serial.println("Failed to start TWAI driver");
    return;
  }

  Serial.println("TWAI (CAN) Receiver initialized");
}

void loop() {
  twai_message_t message;
  // Receive a TWAI message
  if (twai_receive(&message, pdMS_TO_TICKS(1000)) == ESP_OK) {
    Serial.print("Received a message with ID: 0x");
    Serial.print(message.identifier, HEX);

    if (message.rtr) {
      Serial.println(" [Remote Request Frame]");
    } else {
      Serial.print(" Data Length: ");
      Serial.println(message.data_length_code);
      for (int i = 0; i < message.data_length_code; i++) {
        Serial.print((char)message.data[i]);
      }
      Serial.println();
    }
  } else {
    // No message received within 1 second
    Serial.println("No message received");
  }
}

also in Arduino ide examples > esp > twai > twaireceive code is not working CODE:

/* ESP32 TWAI receive example.
  Receive messages and sends them over serial.

  Connect a CAN bus transceiver to the RX/TX pins.
  For example: SN65HVD230

  TWAI_MODE_LISTEN_ONLY is used so that the TWAI controller will not influence the bus.

  The API gives other possible speeds and alerts:
  https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/twai.html

  Example output from a can bus message:
  -> Message received
  -> Message is in Standard Format
  -> ID: 604
  -> Byte: 0 = 00, 1 = 0f, 2 = 13, 3 = 02, 4 = 00, 5 = 00, 6 = 08, 7 = 00

  Example output with alerts:
  -> Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
  -> Bus error count: 171
  -> Alert: The RX queue is full causing a received frame to be lost.
  -> RX buffered: 4  RX missed: 46 RX overrun 0

  created 05-11-2022 by Stephan Martin (designer2k2)
*/

#include "driver/twai.h"

// Pins used to connect to CAN bus transceiver:
#define RX_PIN 4
#define TX_PIN 5

// Intervall:
#define POLLING_RATE_MS 1000

static bool driver_installed = false;

void setup() {
  // Start Serial:
  Serial.begin(115200);

  // Initialize configuration structures using macro initializers
  twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT((gpio_num_t)TX_PIN, (gpio_num_t)RX_PIN, TWAI_MODE_LISTEN_ONLY);
  twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();  //Look in the api-reference for other speed sets.
  twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();

  // Install TWAI driver
  if (twai_driver_install(&g_config, &t_config, &f_config) == ESP_OK) {
    Serial.println("Driver installed");
  } else {
    Serial.println("Failed to install driver");
    return;
  }

  // Start TWAI driver
  if (twai_start() == ESP_OK) {
    Serial.println("Driver started");
  } else {
    Serial.println("Failed to start driver");
    return;
  }

  // Reconfigure alerts to detect frame receive, Bus-Off error and RX queue full states
  uint32_t alerts_to_enable = TWAI_ALERT_RX_DATA | TWAI_ALERT_ERR_PASS | TWAI_ALERT_BUS_ERROR | TWAI_ALERT_RX_QUEUE_FULL;
  if (twai_reconfigure_alerts(alerts_to_enable, NULL) == ESP_OK) {
    Serial.println("CAN Alerts reconfigured");
  } else {
    Serial.println("Failed to reconfigure alerts");
    return;
  }

  // TWAI driver is now successfully installed and started
  driver_installed = true;
}

static void handle_rx_message(twai_message_t& message) {
  // Process received message
  if (message.extd) {
    Serial.println("Message is in Extended Format");
  } else {
    Serial.println("Message is in Standard Format");
  }
  Serial.printf("ID: %x\nByte:", message.identifier);
  if (!(message.rtr)) {
    for (int i = 0; i < message.data_length_code; i++) {
      Serial.printf(" %d = %02x,", i, message.data[i]);
    }
    Serial.println("");
  }
}

void loop() {
  if (!driver_installed) {
    // Driver not installed
    delay(1000);
    return;
  }
  // Check if alert happened
  uint32_t alerts_triggered;
  twai_read_alerts(&alerts_triggered, pdMS_TO_TICKS(POLLING_RATE_MS));
  twai_status_info_t twaistatus;
  twai_get_status_info(&twaistatus);

  // Handle alerts
  if (alerts_triggered & TWAI_ALERT_ERR_PASS) {
    Serial.println("Alert: TWAI controller has become error passive.");
  }
  if (alerts_triggered & TWAI_ALERT_BUS_ERROR) {
    Serial.println("Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.");
    Serial.printf("Bus error count: %d\n", twaistatus.bus_error_count);
  }
  if (alerts_triggered & TWAI_ALERT_RX_QUEUE_FULL) {
    Serial.println("Alert: The RX queue is full causing a received frame to be lost.");
    Serial.printf("RX buffered: %d\t", twaistatus.msgs_to_rx);
    Serial.printf("RX missed: %d\t", twaistatus.rx_missed_count);
    Serial.printf("RX overrun %d\n", twaistatus.rx_overrun_count);
  }

  // Check if message is received
  if (alerts_triggered & TWAI_ALERT_RX_DATA) {
    // One or more messages received. Handle all.
    twai_message_t message;
    while (twai_receive(&message, 0) == ESP_OK) {
      handle_rx_message(message);
    }
  }
}

and RESULT:

12:21:11.915 -> Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
12:21:11.915 -> Bus error count: 118
12:21:12.909 -> Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
12:21:12.909 -> Bus error count: 119
12:21:12.909 -> Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
12:21:12.909 -> Bus error count: 120
12:21:13.901 -> Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
12:21:13.901 -> Bus error count: 121

I want to work with TWAI library. Because as a result I will use ESP32 s3 and this library can not support ESP32 S3.

Upvotes: 0

Views: 1284

Answers (1)

user27814533
user27814533

Reputation: 1

I use this code to run a CAN-BUS between a ESP32-S3 and an ESP32 compiled with ESP32-core Version 2.0.17 (not core-Version 3.X !) ("classical") with CAN-BUS tranceivers TJA1051 which uses this library https://github.com/handmade0octopus/ESP32-TWAI-CAN/tree/master

        // project remarks:
    // On a ESP32-S3-board with DUAL-USB-C-connector the one that is shown as USB-enhanced SERIAL CH434
    // is the one that used by Serial.

    // MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START *
    // a detailed explanation how these macros work is given in this tutorial
    // https://forum.arduino.cc/t/comfortable-serial-debug-output-short-to-write-fixed-text-name-and-content-of-any-variable-code-example/888298

    #define dbg(myFixedText, variableName) \
      Serial.print( F(#myFixedText " "  #variableName"=") ); \
      Serial.println(variableName);

    #define dbgi(myFixedText, variableName,timeInterval) \
      { \
        static unsigned long intervalStartTime; \
        if ( millis() - intervalStartTime >= timeInterval ){ \
          intervalStartTime = millis(); \
          Serial.print( F(#myFixedText " "  #variableName"=") ); \
          Serial.println(variableName); \
        } \
      }

    #define dbgc(myFixedText, variableName) \
      { \
        static long lastState; \
        if ( lastState != variableName ){ \
          Serial.print( F(#myFixedText " "  #variableName" changed from ") ); \
          Serial.print(lastState); \
          Serial.print( F(" to ") ); \
          Serial.println(variableName); \
          lastState = variableName; \
        } \
      }

    #define dbgcf(myFixedText, variableName) \
      { \
        static float lastState; \
        if ( lastState != variableName ){ \
          Serial.print( F(#myFixedText " "  #variableName" changed from ") ); \
          Serial.print(lastState); \
          Serial.print( F(" to ") ); \
          Serial.println(variableName); \
          lastState = variableName; \
        } \
      }
    // MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END *

    /*
      Serial.begin(115200);
      Serial.println("Setup-Start");
      PrintFileNameDateTime();

      BlinkHeartBeatLED(OnBoard_LED,250);
      static unsigned long MyTestTimer;
      if ( TimePeriodIsOver(MyTestTimer,1000) ) {
    */

    #include <ESP32-TWAI-CAN.hpp>

    // Showcasing simple use of ESP32-TWAI-CAN library driver.

    // Default for ESP32
    const byte CAN_TX = 5; // which means connect GPIO-Pin with this number with the Tx-output on the CAN-transeiver
    const byte CAN_RX = 4; // which means connect GPIO-Pin with this number with the Rx-input  on the CAN-transeiver

    CanFrame rxFrame;
    int myCounter;

    unsigned long myLinksBlinkerTimer;
    unsigned long myRechtsBlinkerTimer;

    const byte linksBlinkerPin  = 1;
    const byte rechtsBlinkerPin = 2;
    const byte fahrlichtPin     = 42;

    const byte linksBlinkerBitFilter  = 0b00000001;
    const byte rechtsBlinkerBitFilter = 0b00000010;
    const byte FahrlichtBitFilter     = 0b00000100;

    const byte linksBlinkerBitClear  = ~linksBlinkerBitFilter;
    const byte rechtsBlinkerBitClear = ~rechtsBlinkerBitFilter;
    const byte FahrlichtBitClear     = ~FahrlichtBitFilter;




    const byte onBoard_LED      = 38;
    void setup() {
      digitalWrite(fahrlichtPin,     LOW);
      digitalWrite(linksBlinkerPin,  LOW);
      digitalWrite(rechtsBlinkerPin, LOW);
      pinMode(linksBlinkerPin,  OUTPUT);
      pinMode(rechtsBlinkerPin, OUTPUT);
      pinMode(fahrlichtPin,     OUTPUT);

      Serial.begin(115200);
      Serial.println("Setup-Start");
      PrintFileNameDateTime();
      Serial.println();

      Serial.print("linksBlinkerBitFilter binär:");
      Serial.println(linksBlinkerBitFilter, BIN);

      Serial.print("linksBlinkerBitClear binär:");
      Serial.println(linksBlinkerBitClear, BIN);
      
      // You can set custom size for the queues - those are default
      byte QueueSize = 5;
      ESP32Can.setRxQueueSize(QueueSize);
      ESP32Can.setTxQueueSize(QueueSize);
      Serial.print("ESP32Can.setRxQueueSize(");
      Serial.print(QueueSize);
      Serial.println(")");
      Serial.print("ESP32Can.setTxQueueSize(");
      Serial.print(QueueSize);
      Serial.println(")");

      int CAN_Speed = 500;
      Serial.print("ESP32Can.begin(ESP32Can.convertSpeed(");
      Serial.print(CAN_Speed);
      Serial.print("), CAN_TX=");
      Serial.print(CAN_TX);
      Serial.print(", CAN_RX=");
      Serial.print(CAN_RX);
      Serial.print(", 10, 10) )");
      Serial.println();

      if (ESP32Can.begin(ESP32Can.convertSpeed(CAN_Speed), CAN_TX, CAN_RX, 10, 10) ) {
        Serial.println("CAN bus started successfully!");
      }
      else {
        Serial.println("starting CAN bus failed!");
      }
    }


    void loop() {

      BlinkHeartBeatLED(onBoard_LED, 250);

      static byte links;
      static byte rechts;
      
      static unsigned long MyTestTimer;

      /*
        if ( TimePeriodIsOver(myLinksBlinkerTimer, 400) ) {
          digitalWrite(linksBlinkerPin, !digitalRead(linksBlinkerPin) );
        }

        if ( TimePeriodIsOver(myRechtsBlinkerTimer, 250) ) {
          digitalWrite(rechtsBlinkerPin, !digitalRead(rechtsBlinkerPin) );
        }
      */

      // You can set custom timeout, default is 1000 milliseconds
      if (ESP32Can.readFrame(rxFrame, 100)) {
        // Comment out if too many frames
        Serial.printf("Received frame: %03X  \r\n", rxFrame.identifier);
        if (rxFrame.identifier == 0x7FF) {  // Standard OBD2 frame responce ID
          //dbgc("LR",rxFrame.data[7]);

          // links = rxFrame.data[7] & 0b00000001; // xxy
          links = rxFrame.data[7] & linksBlinkerBitFilter;
          
          dbgc("L",links);
          if ( links == 1) {
            digitalWrite(linksBlinkerPin, HIGH);
            //Serial.println("links HIGH");
          }
          else {
            digitalWrite(linksBlinkerPin, LOW);;
            //Serial.println("links LOW");
          }

          rechts = rxFrame.data[7] & 0b00000010;
          dbgc("R",rechts);
          if (rechts == 0b00000010) {
            digitalWrite(rechtsBlinkerPin, HIGH);
            //Serial.println("rechts HIGH");
          }
          else {
            digitalWrite(rechtsBlinkerPin, LOW);;
            //Serial.println("rechts LOW");
          }
        }
      }


      if ( TimePeriodIsOver(MyTestTimer, 1000) ) {
        myCounter++;
        if (myCounter > 999) {
          myCounter = 0;
        }
        sendCanFrame('A', myCounter);
      }



    }


    void sendCanFrame(uint8_t obdId, int Number) {
      char myDigitBuffer[10] = "         ";
      itoa(Number, myDigitBuffer, 10); // itoa convert integer to ASCII-coded char-array
      CanFrame myDataFrame = { 0 };
      //obdFrame.identifier = 0x7DF; // Default OBD2 address;
      myDataFrame.identifier = 0x7FF;
      myDataFrame.extd = 0;
      myDataFrame.data_length_code = 8;

      myDataFrame.data[0] = myDigitBuffer[0];
      myDataFrame.data[1] = myDigitBuffer[1];
      myDataFrame.data[2] = myDigitBuffer[2];
      myDataFrame.data[3] = 'H';
      myDataFrame.data[4] = 'e';
      myDataFrame.data[5] = 'l';
      myDataFrame.data[6] = 'l';
      myDataFrame.data[7] = 'o';
      // Accepts both pointers and references
      printCanFrame(myDataFrame);
      ESP32Can.writeFrame(myDataFrame);  // timeout defaults to 1 ms
    }


    void printCanFrame(CanFrame p_CAN_Frame) {
      Serial.println("sending CAN-frame");
      Serial.print("identifier=");
      Serial.print(p_CAN_Frame.identifier, HEX);
      Serial.print(" frame length=");
      Serial.print(p_CAN_Frame.data_length_code);
      Serial.print(" data as ASCII-Code#");

      for (byte IdxNr = 0; IdxNr < 8; IdxNr++) {
        Serial.print(char(p_CAN_Frame.data[IdxNr]) );
      }
      Serial.print("#");
      Serial.println();
    }


    // helper-functions
    void PrintFileNameDateTime() {
      Serial.println( F("Code running comes from file ") );
      Serial.println( F(__FILE__) );
      Serial.print( F("  compiled ") );
      Serial.print( F(__DATE__) );
      Serial.print( F(" ") );
      Serial.println( F(__TIME__) );
    }


    // easy to use helper-function for non-blocking timing
    boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
      unsigned long currentMillis  = millis();
      if ( currentMillis - startOfPeriod >= TimePeriod ) {
        // more time than TimePeriod has elapsed since last time if-condition was true
        startOfPeriod = currentMillis; // a new period starts right here so set new starttime
        return true;
      }
      else return false;            // actual TimePeriod is NOT yet over
    }


    void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
      static unsigned long MyBlinkTimer;
      pinMode(IO_Pin, OUTPUT);

      if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
        digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
      }
    }

ESP32-code

        // MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START *
    // a detailed explanation how these macros work is given in this tutorial
    // https://forum.arduino.cc/t/comfortable-serial-debug-output-short-to-write-fixed-text-name-and-content-of-any-variable-code-example/888298

    #define dbg(myFixedText, variableName) \
      Serial.print( F(#myFixedText " "  #variableName"=") ); \
      Serial.println(variableName);

    #define dbgi(myFixedText, variableName,timeInterval) \
      { \
        static unsigned long intervalStartTime; \
        if ( millis() - intervalStartTime >= timeInterval ){ \
          intervalStartTime = millis(); \
          Serial.print( F(#myFixedText " "  #variableName"=") ); \
          Serial.println(variableName); \
        } \
      }

    #define dbgc(myFixedText, variableName) \
      { \
        static long lastState; \
        if ( lastState != variableName ){ \
          Serial.print( F(#myFixedText " "  #variableName" changed from ") ); \
          Serial.print(lastState); \
          Serial.print( F(" to ") ); \
          Serial.println(variableName); \
          lastState = variableName; \
        } \
      }

    #define dbgcf(myFixedText, variableName) \
      { \
        static float lastState; \
        if ( lastState != variableName ){ \
          Serial.print( F(#myFixedText " "  #variableName" changed from ") ); \
          Serial.print(lastState); \
          Serial.print( F(" to ") ); \
          Serial.println(variableName); \
          lastState = variableName; \
        } \
      }
    // MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END *

    /*
      Serial.begin(115200);
      Serial.println("Setup-Start");
      PrintFileNameDateTime();

      BlinkHeartBeatLED(OnBoard_LED,250);
      static unsigned long MyTestTimer;
      if ( TimePeriodIsOver(MyTestTimer,1000) ) {
    */

    #include <ESP32-TWAI-CAN.hpp>
    #include <SafeString.h>

    // Showcasing simple use of ESP32-TWAI-CAN library driver.

    // Default for ESP32
    const byte CAN_TX = 5; // which means connect GPIO-Pin with this number with the Tx-output on the CAN-transeiver
    const byte CAN_RX = 4; // which means connect GPIO-Pin with this number with the Rx-input  on the CAN-transeiver

    CanFrame rxFrame;
    int myCounter;

    cSF(rxData_SS, 16);

    unsigned long myLinksBlinkerTimer;
    unsigned long myRechtsBlinkerTimer;
    boolean linksBlinkerAn  = false;
    boolean rechtsBlinkerAn = false;

    const byte linksBlinkerBitFilter  = 0b00000001;
    const byte rechtsBlinkerBitFilter = 0b00000010;
    const byte FahrlichtBitFilter     = 0b00000100;

    const byte linksBlinkerBitClear  = ~linksBlinkerBitFilter;
    const byte rechtsBlinkerBitClear = ~rechtsBlinkerBitFilter;
    const byte FahrlichtBitClear     = ~FahrlichtBitFilter;

    const byte linksBlinkerPin   = 26;
    const byte rechtssBlinkerPin = 27;

    const byte switchedOn  = LOW;
    const byte switchedOff = HIGH;



    void setup() {
      Serial.begin(115200);
      Serial.println("Setup-Start");
      PrintFileNameDateTime();
      Serial.println();

      pinMode(linksBlinkerPin, INPUT_PULLUP);
      pinMode(rechtssBlinkerPin, INPUT_PULLUP);

      // You can set custom size for the queues - those are default
      byte QueueSize = 5;
      ESP32Can.setRxQueueSize(QueueSize);
      ESP32Can.setTxQueueSize(QueueSize);
      Serial.print("ESP32Can.setRxQueueSize(");
      Serial.print(QueueSize);
      Serial.println(")");
      Serial.print("ESP32Can.setTxQueueSize(");
      Serial.print(QueueSize);
      Serial.println(")");

      int CAN_Speed = 500;
      Serial.print("ESP32Can.begin(ESP32Can.convertSpeed(");
      Serial.print(CAN_Speed);
      Serial.print("), CAN_TX=");
      Serial.print(CAN_TX);
      Serial.print(", CAN_RX=");
      Serial.print(CAN_RX);
      Serial.print(", 10, 10) )");
      Serial.println();

      if (ESP32Can.begin(ESP32Can.convertSpeed(CAN_Speed), CAN_TX, CAN_RX, 10, 10) ) {
        Serial.println("CAN bus started successfully!");
      }
      else {
        Serial.println("starting CAN bus failed!");
      }
      dbg("IO", digitalRead(linksBlinkerPin) );
      dbg("IO", digitalRead(rechtssBlinkerPin) );

    }


    void loop() {
      static unsigned long MyTestTimer;

      dbgc("IO", digitalRead(linksBlinkerPin) );
      dbgc("IO", digitalRead(rechtssBlinkerPin) );

      if ( TimePeriodIsOver(myLinksBlinkerTimer, 1000) ) {
        linksBlinkerAn  = !linksBlinkerAn;
      }


      if ( TimePeriodIsOver(myRechtsBlinkerTimer, 250) ) {
        //rechtsBlinkerAn = !rechtsBlinkerAn;
      }


      if ( TimePeriodIsOver(MyTestTimer, 50) ) {
        //myCounter++;
        if (myCounter > 999) {
          myCounter = 0;
        }
        //sendCanFrame('A', myCounter);
      }

      // You can set custom timeout, default is 1000 milliseconds
      if (ESP32Can.readFrame(rxFrame, 100)) {
        // Comment out if too many frames
        //Serial.printf("Received frame: %03X  \r\n", rxFrame.identifier);
        if (rxFrame.identifier == 0x7FF) {  // Standard OBD2 frame responce ID
          rxData_SS = "";

          for (byte i = 0; i < 8; i++) {
            rxData_SS += char( rxFrame.data[i] );
          }
          Serial.println(rxData_SS);
        }
      }
    }


    void sendCanFrame(uint8_t obdId, int Number) {
      char myDigitBuffer[10] = "         ";
      itoa(Number, myDigitBuffer, 10); // itoa convert integer to ASCII-coded char-array
      CanFrame myDataFrame = { 0 };
      //obdFrame.identifier = 0x7DF; // Default OBD2 address;
      myDataFrame.identifier = 0x7FF;
      myDataFrame.extd = 0;
      myDataFrame.data_length_code = 8;

      myDataFrame.data[0] = myDigitBuffer[0];
      myDataFrame.data[1] = myDigitBuffer[1];
      myDataFrame.data[2] = myDigitBuffer[2];
      myDataFrame.data[3] = 'H';
      myDataFrame.data[4] = 'e';
      myDataFrame.data[5] = 'l';
      myDataFrame.data[6] = 'l';

      if (linksBlinkerAn) {
        //myDataFrame.data[7] = myDataFrame.data[7] | 0b00000001;
        myDataFrame.data[7] = myDataFrame.data[7] | linksBlinkerBitFilter;
      }
      else {
        myDataFrame.data[7] = myDataFrame.data[7] & linksBlinkerBitClear; // xxy
      }

      if (rechtsBlinkerAn) {
        myDataFrame.data[7] = myDataFrame.data[7] | rechtsBlinkerBitFilter;
      }
      else {
        myDataFrame.data[7] = myDataFrame.data[7] & rechtsBlinkerBitClear;
      }

      dbgc("LR", myDataFrame.data[7]);

      //myDataFrame.data[7] = 'o';
      // Accepts both pointers and references
      printCanFrame(myDataFrame);
      ESP32Can.writeFrame(myDataFrame);  // timeout defaults to 1 ms
    }


    void printCanFrame(CanFrame p_CAN_Frame) {
      Serial.println("sending CAN-frame");
      Serial.print("identifier=");
      Serial.print(p_CAN_Frame.identifier, HEX);
      Serial.print(" frame length=");
      Serial.print(p_CAN_Frame.data_length_code);
      Serial.print(" data as ASCII-Code#");

      for (byte IdxNr = 0; IdxNr < 8; IdxNr++) {
        Serial.print(char(p_CAN_Frame.data[IdxNr]) );
      }
      Serial.print("#");
      Serial.println();
    }


    // helper-functions
    void PrintFileNameDateTime() {
      Serial.println( F("Code running comes from file ") );
      Serial.println( F(__FILE__) );
      Serial.print( F("  compiled ") );
      Serial.print( F(__DATE__) );
      Serial.print( F(" ") );
      Serial.println( F(__TIME__) );
    }


    // easy to use helper-function for non-blocking timing
    boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
      unsigned long currentMillis  = millis();
      if ( currentMillis - startOfPeriod >= TimePeriod ) {
        // more time than TimePeriod has elapsed since last time if-condition was true
        startOfPeriod = currentMillis; // a new period starts right here so set new starttime
        return true;
      }
      else return false;            // actual TimePeriod is NOT yet over
    }


    void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
      static unsigned long MyBlinkTimer;
      pinMode(IO_Pin, OUTPUT);

      if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
        digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
      }
    }

Upvotes: 0

Related Questions