The project is to decode with a CAN bus data received by a sensor via an Arduino Mega card.
I have the following program everything works I can read the data frames in Hexadecimal.
What I want is to isolate in this frame the bytes 1-2 (humidity) 3-4 (temperature) 5-6 (C02) currently in hex
and convert them in real time to decimal
I am interested here to replace for example the "9C 25" by 22 degrees converted into decimal, it is necessary to reverse in "25 9C" because of the MSB LSB also.
I saw on the internet that there would be functions like strtoul() by writing this way " nResult= (nResult << 8) | (strtoul(pch, NULL, 16) & 0xff); "
but I don't really understand.
My actual code :
#include <SPI.h>
#include <SD.h>
#include <mcp_can.h>
#include "mcp2515_can.h"
File myFile;
#define CAN_2515
const int SPI_CS_PIN = 53;
const int CAN_INT_PIN = 2;
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
unsigned char flagRecv = 0;
unsigned char len = 0;
unsigned char buf[8];
char str[20];
void setup()
{
SERIAL_PORT_MONITOR.begin(115200); // screen rate Arduino monitor
attachInterrupt(digitalPinToInterrupt(CAN_INT_PIN), MCP2515_ISR, FALLING); // start interrupt
while (CAN_OK != CAN.begin(CAN_500KBPS)) // init can bus : baudrate = 500k
{
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL_PORT_MONITOR.println("CAN init ok!");
if (!SD.begin(4))
{
SERIAL_PORT_MONITOR.println("SD init fail!");
while (1);
}
SERIAL_PORT_MONITOR.println("SD init OK.");
}
void MCP2515_ISR() { flagRecv = 1;}
void loop() {
if (flagRecv) { // check if get data
flagRecv = 0; // clear flag
unsigned long id = 0;
myFile = SD.open("can.csv", FILE_WRITE);
while (CAN_MSGAVAIL == CAN.checkReceive()) {
CAN.readMsgBufID(&id, &len, buf); // read data, len: data length, buf: data buf
SERIAL_PORT_MONITOR.print(id);
SERIAL_PORT_MONITOR.print(",");
myFile.print(id);
myFile.print(",");
for (int i = 0; i < len; i++) {
SERIAL_PORT_MONITOR.print(buf[i]);
SERIAL_PORT_MONITOR.print(",");
myFile.print(buf[i]);
myFile.print(",");
}
SERIAL_PORT_MONITOR.println();
myFile.println();
}
myFile.close();
}
}
// END FILE
The project is to decode with a CAN bus data received by a sensor via an Arduino Mega card.
I have the following program everything works I can read the data frames in Hexadecimal.
What I want is to isolate in this frame the bytes 1-2 (humidity) 3-4 (temperature) 5-6 (C02) currently in hex and convert them in real time to decimal :
for exemple i receive :
" Get data from ID: 0x18FF0AEB
-> 5D AF 9C 25 64 0 64 0 "
I am interested here to replace for example the "9C 25" by 22 degrees converted into decimal, it is necessary to reverse in "25 9C" because of the MSB LSB also.
but I don't really understand how to to that
My actual code :
#include <SPI.h>
#include "mcp2515_can.h"
#define CAN_2515
const int SPI_CS_PIN = 53;
const int CAN_INT_PIN = 2;
mcp2515_can CAN(SPI_CS_PIN);
void setup() {
SERIAL_PORT_MONITOR.begin(115200);
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL_PORT_MONITOR.println("CAN init ok!");
}
void loop() {
unsigned char len = 0;
unsigned char buf[8];
if (CAN_MSGAVAIL == CAN.checkReceive()) { // check if data coming
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf
unsigned long canId = CAN.getCanId();
SERIAL_PORT_MONITOR.println("-----------------------------");
SERIAL_PORT_MONITOR.print("Get data from ID: 0x");
SERIAL_PORT_MONITOR.println(canId, HEX);
for (int i = 0; i < len; i++) { // print the data
SERIAL_PORT_MONITOR.print(buf[i], HEX);
SERIAL_PORT_MONITOR.print("\t");
}
SERIAL_PORT_MONITOR.println();
}
}
Given below a Counting Method (Positional Factors are being multiplied by the corresponding Positional Weights) to convert the given hex number into decimal number.
byte myDigit[4];
int i = 0;
void setup()
{
Serial.begin(9600);
int y = 0x259C;
do
{
myDigit[i] = y % 10; //getting the decimal digits of the target decimal number: 8 2 6 9
y = y / 10;
i++;
}
while (y != 0);
unsigned int myDec = myDigit[3] * 1000 + myDigit[2] * 100
+ myDigit[1] * 10 + myDigit[0] * 1;
myDec = (int)(myDec * 0.3125 - 273)/100;
Serial.println(myDec); //shows: 27
}
void loop() {}
uint8_t sample_data[8] ={0x5D, 0xAF, 0x9C, 0x25, 0x64, 0x00, 0x64, 0x00}; < this value updates all the time
This frame that I gave you is updated in real time in my monitor in the buf[i] ,
do you know if it is possible to replace buf[i] with your uint8_t sample_data[8] in your code?
And place your code in this loop of my code to have the concersion in decimal in real time :
for (int i = 0; i < len; i++) { // print the data
SERIAL_PORT_MONITOR.print(buf[i], HEX);
SERIAL_PORT_MONITOR.print("\t");
}