I’m using a Rak 4631 with the CANBUS module Rak 13006. I basically have two seperate pieces of code that I want to mesh into one file. Below is the first file which simply reads the 7th byte from a CANBUS message and prints it to serial monitor, This code works perfectly fine:
#include <Rak_CAN.h>
void setup () {
pinMode(WB_IO2, OUTPUT);
digitalWrite(WB_IO2, HIGH); // Enable power supply.
delay(300);
Serial.begin (115200) ;
while (!Serial) {
delay (50) ;
}
Rak_Can.init();
Serial.print ("sizeof (RAK_CAN_Settings): ") ;
Serial.print (sizeof (RAK_CAN_Settings)) ;
Serial.println (" bytes") ;
Serial.println (“Configure ACAN2518”) ;
RAK_CAN_Settings settings (RAK_CAN_Settings::OSC_40MHz, 500 * 1000) ; // CAN bit rate 500 kb/s
settings.mRequestedMode = RAK_CAN_Settings::Normal20B ;
const uint32_t errorCode = Rak_Can.begin (settings, [] { Rak_Can.isr () ; }) ;
if (errorCode == 0) {
Serial.print ("Bit Rate prescaler: ") ;
Serial.println (settings.mBitRatePrescaler) ;
Serial.print ("Phase segment 1: ") ;
Serial.println (settings.mPhaseSegment1) ;
Serial.print ("Phase segment 2: ") ;
Serial.println (settings.mPhaseSegment2) ;
Serial.print ("SJW:") ;
Serial.println (settings.mSJW) ;
Serial.print ("Actual bit rate: ") ;
Serial.print (settings.actualBitRate ()) ;
Serial.println (" bit/s") ;
Serial.print ("Exact bit rate ? ") ;
Serial.println (settings.exactBitRate () ? "yes" : "no") ;
Serial.print ("Sample point: ") ;
Serial.print (settings.samplePointFromBitStart ()) ;
Serial.println ("%") ;
} else {
Serial.print ("Configuration error 0x") ;
Serial.println (errorCode, HEX) ;
}
}
static uint32_t gBlinkLedDate = 0 ;
static uint32_t gReceivedFrameCount = 0 ;
void loop () {
delay(3000);
CANMessage frame ;
#if BOARDFLAG
if (Rak_Can.IntrruptFlag == 1)
#endif
{
Rak_Can.isr_core();
Serial.println("hell00");
if (Rak_Can.receive (frame)) {
Serial.println("hell001");
// if (!frame.rtr && (!frame.ext) && (frame.id == 0x05)) {
if (frame.id == 0x6B0) {
Serial.println("hell002");
gReceivedFrameCount ++ ;
Serial.print(map(frame.data[7]/2, 0, 95, 0, 100));
}
}
#if BOARDFLAG
Rak_Can.IntrruptFlag = 0;
#endif
}
}
My other piece of code uses an analog I/O pin to read a voltage from a wire, then transmit that value mapped to a battery percentage over LoRa. This code also works perfectly fine:
#include <Arduino.h>
#include <SX126x-RAK4630.h>
#include <SPI.h>
#include <Wire.h>
// Function declarations
void OnTxDone(void);
void OnTxTimeout(void);
#ifdef NRF52_SERIES
#define LED_BUILTIN 35
#endif
// Define LoRa parameters
#define RF_FREQUENCY 868300000 // Hz
#define TX_OUTPUT_POWER 22 // dBm
#define LORA_BANDWIDTH 0 // [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: Reserved]
#define LORA_SPREADING_FACTOR 7 // [SF7…SF12]
#define LORA_CODINGRATE 1 // [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx
#define LORA_SYMBOL_TIMEOUT 0 // Symbols
#define LORA_FIX_LENGTH_PAYLOAD_ON false
#define LORA_IQ_INVERSION_ON false
#define RX_TIMEOUT_VALUE 3000
#define TX_TIMEOUT_VALUE 3000
static RadioEvents_t RadioEvents;
static uint8_t TxdBuffer[64];
int BatteryPercentage = 0;
int BatteryPercentageAverage = 0;
int oldBatteryPercentage = 0;
int chargeSum = 0;
int countOfChargesAdded = 0;
bool firstDisplaySet = false;
void setup()
{
// Initialize LoRa chip.
lora_rak4630_init();
// Initialize Serial for debug output
Serial.begin(115200);
// while(!Serial){delay(10);}
Serial.println("=====================================");
Serial.println(“LoRap2p Tx Test”);
Serial.println("=====================================");
// Initialize the Radio callbacks
RadioEvents.TxDone = OnTxDone;
RadioEvents.RxDone = NULL;
RadioEvents.TxTimeout = OnTxTimeout;
RadioEvents.RxTimeout = NULL;
RadioEvents.RxError = NULL;
RadioEvents.CadDone = NULL;
// Initialize the Radio
Radio.Init(&RadioEvents);
// Set Radio channel
Radio.SetChannel(RF_FREQUENCY);
pinMode(WB_IO4, INPUT);
// Set Radio TX configuration
Radio.SetTxConfig(MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
LORA_SPREADING_FACTOR, LORA_CODINGRATE,
LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
true, 0, 0, LORA_IQ_INVERSION_ON, TX_TIMEOUT_VALUE);
// send();
}
void loop()
{
// Handle Radio events
Radio.IrqProcess();
// We are on FreeRTOS, give other tasks a chance to run
delay(100);
BatteryPercentage = analogRead(WB_IO4); // read the input pin
BatteryPercentage = map(BatteryPercentage, 0, 798, 0, 100);
chargeSum+=BatteryPercentage;
countOfChargesAdded++;
if(countOfChargesAdded==200){
countOfChargesAdded = 0;
BatteryPercentageAverage = chargeSum/200;
chargeSum = 0;
Serial.println(BatteryPercentageAverage);
firstDisplaySet = true;
}
// Serial.println(BatteryPercentage);
send();
yield();
}
/**@brief Function to be executed on Radio Tx Done event
*/
void OnTxDone(void)
{
Serial.println(“OnTxDone”);
delay(5000);
send();
}
/**@brief Function to be executed on Radio Tx Timeout event
*/
void OnTxTimeout(void)
{
Serial.println(“OnTxTimeout”);
}
void send()
{
if(BatteryPercentageAverage != oldBatteryPercentage){
// Convert BatteryPercentage to byte array and store in TxdBuffer
snprintf((char *)TxdBuffer, sizeof(TxdBuffer), “Remaining Charge: %d%%”, BatteryPercentageAverage);
// Send the message, remember to change the length in Radio.Send()
// to be the length of the message. In this example, I'm assuming
// the message length is less than 64, but you should probably add checks for that.
Radio.Send(TxdBuffer, strlen((char *)TxdBuffer));
oldBatteryPercentage = BatteryPercentageAverage;
}else if(!firstDisplaySet){
// Convert BatteryPercentage to byte array and store in TxdBuffer
snprintf((char *)TxdBuffer, sizeof(TxdBuffer), "Remaining Charge: %d%%", BatteryPercentage);
// Send the message, remember to change the length in Radio.Send()
// to be the length of the message. In this example, I'm assuming
// the message length is less than 64, but you should probably add checks for that.
Radio.Send(TxdBuffer, strlen((char *)TxdBuffer));
firstDisplaySet = true;
}
}
Now, I want to take the code to read the 7th byte from CAN BUS and then combine that with the code to transmit over LoRa so that I can send that value to a second Wisblock kit. Below is my code attempting to do that, but it does not work. The code never enters this if statement: if (Rak_Can.receive (frame))
#include <Arduino.h>
#include <SX126x-RAK4630.h>
#include <SPI.h>
#include <Wire.h>
#include <Rak_CAN.h>
// Function declarations
void OnTxDone(void);
void OnTxTimeout(void);
#ifdef NRF52_SERIES
#define LED_BUILTIN 35
#endif
// Define LoRa parameters
#define RF_FREQUENCY 868300000 // Hz
#define TX_OUTPUT_POWER 22 // dBm
#define LORA_BANDWIDTH 0 // [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: Reserved]
#define LORA_SPREADING_FACTOR 7 // [SF7…SF12]
#define LORA_CODINGRATE 1 // [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx
#define LORA_SYMBOL_TIMEOUT 0 // Symbols
#define LORA_FIX_LENGTH_PAYLOAD_ON false
#define LORA_IQ_INVERSION_ON false
#define RX_TIMEOUT_VALUE 3000
#define TX_TIMEOUT_VALUE 3000
static RadioEvents_t RadioEvents;
static uint8_t TxdBuffer[64];
int batteryPercentage = 0;
int oldBatteryPercentage = 0;
void setup()
{
// Initialize LoRa chip.
lora_rak4630_init();
// Initialize Serial for debug output
Serial.begin(115200);
// while(!Serial){delay(10);}
Serial.println("=====================================");
Serial.println(“LoRap2p Tx Test”);
Serial.println("=====================================");
Rak_Can.init();
Serial.print ("sizeof (RAK_CAN_Settings): ") ;
Serial.print (sizeof (RAK_CAN_Settings)) ;
Serial.println (" bytes") ;
Serial.println (“Configure ACAN2518”) ;
RAK_CAN_Settings settings (RAK_CAN_Settings::OSC_40MHz, 500 * 1000) ; // CAN bit rate 500 kb/s
settings.mRequestedMode = RAK_CAN_Settings::Normal20B ;
const uint32_t errorCode = Rak_Can.begin (settings, [] { Rak_Can.isr () ; }) ;
if (errorCode == 0) {
Serial.print ("Bit Rate prescaler: ") ;
Serial.println (settings.mBitRatePrescaler) ;
Serial.print ("Phase segment 1: ") ;
Serial.println (settings.mPhaseSegment1) ;
Serial.print ("Phase segment 2: ") ;
Serial.println (settings.mPhaseSegment2) ;
Serial.print ("SJW:") ;
Serial.println (settings.mSJW) ;
Serial.print ("Actual bit rate: ") ;
Serial.print (settings.actualBitRate ()) ;
Serial.println (" bit/s") ;
Serial.print ("Exact bit rate ? ") ;
Serial.println (settings.exactBitRate () ? "yes" : "no") ;
Serial.print ("Sample point: ") ;
Serial.print (settings.samplePointFromBitStart ()) ;
Serial.println ("%") ;
} else {
Serial.print ("Configuration error 0x") ;
Serial.println (errorCode, HEX) ;
}
// Initialize the Radio callbacks
RadioEvents.TxDone = OnTxDone;
RadioEvents.RxDone = NULL;
RadioEvents.TxTimeout = OnTxTimeout;
RadioEvents.RxTimeout = NULL;
RadioEvents.RxError = NULL;
RadioEvents.CadDone = NULL;
// Initialize the Radio
Radio.Init(&RadioEvents);
// Set Radio channel
Radio.SetChannel(RF_FREQUENCY);
// Set Radio TX configuration
Radio.SetTxConfig(MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
LORA_SPREADING_FACTOR, LORA_CODINGRATE,
LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
true, 0, 0, LORA_IQ_INVERSION_ON, TX_TIMEOUT_VALUE);
// send();
}
static uint32_t gBlinkLedDate = 0 ;
static uint32_t gReceivedFrameCount = 0 ;
void loop()
{
// Handle Radio events
Radio.IrqProcess();
// We are on FreeRTOS, give other tasks a chance to run
delay(1000);
// BatteryPercentage = analogRead(WB_IO4); // read the input pin
// BatteryPercentage = map(BatteryPercentage, 0, 798, 0, 100);
// chargeSum+=BatteryPercentage;
// countOfChargesAdded++;
// if(countOfChargesAdded==200){
// countOfChargesAdded = 0;
// BatteryPercentageAverage = chargeSum/200;
// chargeSum = 0;
// Serial.println(BatteryPercentageAverage);
// firstDisplaySet = true;
// }
CANMessage frame ;
#if BOARDFLAG
if (Rak_Can.IntrruptFlag == 1)
#endif
{
Rak_Can.isr_core();
Serial.println("hell00");
if (Rak_Can.receive (frame)) {
Serial.println("hell001");
// if (!frame.rtr && (!frame.ext) && (frame.id == 0x05)) {
if (frame.id == 0x6B0) {
Serial.println("hell002");
gReceivedFrameCount ++ ;
batteryPercentage = map(frame.data[7]/2, 0, 95, 0, 100);
}
}
#if BOARDFLAG
Rak_Can.IntrruptFlag = 0;
#endif
}
// Serial.println(BatteryPercentage);
send();
yield();
}
/**@brief Function to be executed on Radio Tx Done event
*/
void OnTxDone(void)
{
Serial.println(“OnTxDone”);
delay(5000);
send();
}
/**@brief Function to be executed on Radio Tx Timeout event
*/
void OnTxTimeout(void)
{
Serial.println(“OnTxTimeout”);
}
void send()
{
if(batteryPercentage != oldBatteryPercentage){
// Convert BatteryPercentage to byte array and store in TxdBuffer
snprintf((char *)TxdBuffer, sizeof(TxdBuffer), "Remaining Charge: %d%%", batteryPercentage);
// Send the message, remember to change the length in Radio.Send()
// to be the length of the message. In this example, I'm assuming
// the message length is less than 64, but you should probably add checks for that.
Radio.Send(TxdBuffer, strlen((char *)TxdBuffer));
oldBatteryPercentage = batteryPercentage;
}
}