Hello everyone!
So, I have been reading for hours now trying to solve this problem - so I hope I can reach out to you guys with the following question.
What I want to do:
Read CAN-Bus messages from a car and turn the information in it into a human-readable form.
What I need to do:
- Read the CAN-message with a MCP2515 --> Works
- bitRead() all the bits in one message (8*8=64 bits) and copy them into a new Array in the correct order
This array contains all the bits I need to access. Some information on the Bus is just Boolean using 1 Bit to inform about the On/Off state. Others need to combine certain Bits, convert them into Dec and then offset and multiply them.
I managed to copy all the bits into a char Array[64] called CanMessage
Where my problem is:
I can seem to "copy" a variable combination of bits together to convert them into decimal.
Like I could have 0110110101110111 (the real array would have 64 chars)
Then I need to take like Bit 3 to 8 (so: 101101) and covert this into Dec (so: 45)
I just don't seem to get this...any hints?
--> My code is beneath, based on a CAN example for receiving data.
I tired to commend anything of importance.
Help is very much appreciated!
#include <mcp_can.h>
#include <SPI.h>
long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];
char msgString[128]; // Array to store serial string
char CanMessage[64];
#define CAN0_INT 2 // Set INT to pin 2
MCP_CAN CAN0(5); // Set CS to pin 10
void setup()
{
Serial.begin(115200);
// Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ) == CAN_OK)
Serial.println("MCP2515 Initialized Successfully!");
else
Serial.println("Error Initializing MCP2515...");
CAN0.setMode(MCP_NORMAL); // Set operation mode to normal so the MCP2515 sends acks to received data.
pinMode(CAN0_INT, INPUT); // Configuring pin for /INT input
Serial.println("MCP2515 Library Receive Example...");
}
void loop()
{
char Test[]=""; // Test-Array for a section of the total message to convert to Decimal
if(!digitalRead(CAN0_INT)) // If CAN0_INT pin is low, read receive buffer
{
CAN0.readMsgBuf(&rxId, &len, rxBuf); // Read data: len = data length, buf = data byte(s)
if((rxId & 0x80000000) == 0x80000000) // Determine if ID is standard (11 bits) or extended (29 bits)
sprintf(msgString, "Extended ID: 0x%.8lX DLC: %1d Data:", (rxId & 0x1FFFFFFF), len);
else
sprintf(msgString, "Standard ID: 0x%.3lX DLC: %1d Data:", rxId, len);
Serial.print(msgString);
if((rxId & 0x40000000) == 0x40000000)
{ // Determine if message is a remote request frame.
sprintf(msgString, " REMOTE REQUEST FRAME");
Serial.print(msgString);
} else
{
//len
for(byte i = 0; i<len; i++)
{
byte u=0;
for ( byte Bit=8; Bit>0; Bit--)
{
Serial.print(bitRead(rxBuf[i],Bit-1));
CanMessage[(i*8)+u]=bitRead(rxBuf[i],Bit-1); // But all the 0s and 1s in ONE Array after each other
u++;
}
}
}
// The follwing part is just for testing of the Bits are in the correct order!
Serial.println();
Serial.print("0-7: ");
for ( byte i=0; i<8; i++)
{
Serial.print(CanMessage[i],BIN);
}
Serial.println();
}
//Serial.println(Test[1]);
//Test conversion of a String containing "00101" --> works if I substitute it for "CanMessage"
//long value= strtol(CanMessage, NULL, 2);
//Serial.println(CanMessage);
}
