Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intermittently receiving zeroes on the receiving message. #49

Open
MattLeright opened this issue Sep 18, 2024 · 0 comments
Open

Intermittently receiving zeroes on the receiving message. #49

MattLeright opened this issue Sep 18, 2024 · 0 comments

Comments

@MattLeright
Copy link

Hi Pierre,

Greetings from the USA. Thank you for your library.

I am using your 2517FD CAN driver for Arduino (I am using the Mega) with the Seeed CANFD shield (this has the MCP2518FD) linked here (https://www.seeedstudio.com/CAN-FD-Shield-for-Arduino-p-5604.html) and I am at my wits end with troubleshooting an issue. It seems I can receive messages in loopback mode and can also send messages fine. However, when I receive messages from the other device on the network sometimes I am getting all zeros. The initialization looks to be ok because the begin method returns a 0, or no errors. Also, receive function returns a 1, as expected. I am certain the bit rate, arbitration rate, and Arduino clock speed are set correctly for my application. Below is the output from the Arduino IDE. The bus length is very short and terminated correctly.

I do not, however, think the correct messages are being received by the receive function.

I originally tried using the driver provided by the shield supplier but I couldn’t get it to send CANFD messages. Only CAN 2.0 messages could be sent. At least I can send CANFD messages with your driver.

111, 40, and 0 are the correct values to be received from the bus. 0, 0, and 0 are not. Intermittently I am receiving 0s on the bus. Any ideas why I might be receiving zeroes every other frame or so? I have confirmed the sending node is sending the correct messages using a vector CAN tool.

Any insight would be appreciated.

My code is shown below, which is a work in progress:

`#include <ACAN2517FD.h>
#include <ACAN2517FDFilters.h>
#include <ACAN2517FDSettings.h>
#include <ACANFDBuffer.h>
#include <ACANFD_DataBitRateFactor.h>
#include <CANFDMessage.h>
#include <CANMessage.h>

//——————————————————————————————————————————————————————————————————————————————
// ACAN2517FD Demo in loopback mode, for Arduino Uno
//——————————————————————————————————————————————————————————————————————————————
#include <DFRobot_GP8403.h>
DFRobot_GP8403 dac(&Wire, 0x58);

#include <TimerInterrupt.h>
#include <TimerInterrupt.hpp>
#include <ISR_Timer.h>
#include <ISR_Timer.hpp>

#include <SPI.h>

const float FullScalePressure = 231.46;

//Variable Definitions
unsigned int VoltageCounts = 0;
float Voltage = 0;
float Pressure = 0;
unsigned int Pressure16bitScaled = 0;
unsigned int Pressure16bitScaled2 = 0;
uint8_t PressureLowByte = 0;
uint8_t PressureHighByte = 0;
bool KL15 = 0;
bool IgnStat = 0;
uint8_t IgnStatValue = 1;
bool PushButton = 0;
unsigned int VoltageOffset = 0;
unsigned int VoltageCountsZeroed = 0;
unsigned int PreChargeSwitch = 0;
float PreChargeVoltage = 0;
uint8_t PKBSwitchState = 0;
uint8_t PKBApplyReleaseRequest = 5;
bool ApplyFlag = 0;
bool ReleaseFlag = 0;
uint32_t TimeStamp = 0;
unsigned char flagRecv = 0;
unsigned char len = 0;
// unsigned char buf[MAX_DATA_SIZE];
int32_t ClampForce = 0;
float ClampForce2DynoVoltage = 0.0005;
float DACOutVoltage = 0;
uint16_t DACOutVoltageScaled = 0;

//——————————————————————————————————————————————————————————————————————————————
// Very very important: put a 10kΩ resistor between CS and VDD of MCP2517FD

static const byte MCP2517_CS = 9; // CS input of MCP2517
static const byte MCP2517_INT = 2; // INT output of MCP2517

//——————————————————————————————————————————————————————————————————————————————
// ACAN2517FD Driver object
//——————————————————————————————————————————————————————————————————————————————

ACAN2517FD can(MCP2517_CS, SPI, MCP2517_INT);

//——————————————————————————————————————————————————————————————————————————————
// SETUP
//——————————————————————————————————————————————————————————————————————————————

void setup() {
//--- Start serial
Serial.begin(115200);
//--- Wait for serial (blink led at 10 Hz during waiting)
while (!Serial) {
delay(50);
}
//----------------------------------- Begin SPI
SPI.begin();

delay(1000);

//--- Configure ACAN2517FD
Serial.print("sizeof (ACAN2517FDSettings): ");
Serial.print(sizeof(ACAN2517FDSettings));
Serial.println(" bytes");
Serial.println("Configure ACAN2517FD");
//--- For version >= 2.1.0

delay(1000);

ACAN2517FDSettings settings(ACAN2517FDSettings::OSC_20MHz, 1000UL * 1000UL, DataBitRateFactor::x1);
//--- For version < 2.1.0
// ACAN2517FDSettings settings (ACAN2517FDSettings::OSC_20MHz, 1000UL * 1000UL, ACAN2517FDSettings::DATA_BITRATE_x1) ;
//settings.mRequestedMode = ACAN2517FDSettings::InternalLoopBack ; // Select loopback mode
//--- Default values are too high for an Arduino Uno that contains 2048 bytes of RAM: reduce them
settings.mDriverTransmitFIFOSize = 1;
settings.mControllerTransmitFIFOSize = 1;
settings.mDriverReceiveFIFOSize = 1;
settings.mControllerReceiveFIFOSize = 27;

//--- RAM Usage

delay(1000);

Serial.print("MCP2517FD RAM Usage: ");
Serial.print(settings.ramUsage());
Serial.println(" bytes");

delay(1000);

settings.mArbitrationPhaseSegment2 = 4;
settings.mRequestedMode = ACAN2517FDSettings::NormalFD;
settings.mControllerTXQSize = 0;

//--- Begin
const uint32_t errorCode = can.begin(settings, [] {
can.isr();
});
Serial.println(errorCode);

if (errorCode == 0) {
Serial.print("Bit Rate prescaler: ");
Serial.println(settings.mBitRatePrescaler);
Serial.print("Arbitration Phase segment 1: ");
Serial.println(settings.mArbitrationPhaseSegment1);
Serial.print("Arbitration Phase segment 2: ");
Serial.println(settings.mArbitrationPhaseSegment2);
Serial.print("Arbitration SJW:");
Serial.println(settings.mArbitrationSJW);
Serial.print("Actual Arbitration Bit Rate: ");
Serial.print(settings.actualArbitrationBitRate());
Serial.println(" bit/s");
Serial.print("Exact Arbitration Bit Rate ? ");
Serial.println(settings.exactArbitrationBitRate() ? "yes" : "no");
Serial.print("Arbitration Sample point: ");
Serial.print(settings.arbitrationSamplePointFromBitStart());
Serial.println("%");
} else {
Serial.print("Configuration error 0x");
Serial.println(errorCode, HEX);
}

pinMode(22, INPUT_PULLUP);
pinMode(23, INPUT_PULLUP);
pinMode(24, INPUT_PULLUP);
pinMode(18, INPUT_PULLUP);
}

//——————————————————————————————————————————————————————————————————————————————
// LOOP
//——————————————————————————————————————————————————————————————————————————————

//——————————————————————————————————————————————————————————————————————————————

void loop() {

// Read KL15 input switch, if TRUE then enter while loop below.
KL15 = digitalRead(22);

if (KL15 == 0) {
VoltageOffset = analogRead(A0);
}

while (KL15 == 0) {

// Read Pressure Transmitter Voltage and Zero
VoltageCounts = analogRead(A0);
VoltageCountsZeroed = VoltageCounts - VoltageOffset;

// Calculate PreChargeSwitch Voltage
PreChargeSwitch = analogRead(A1);
PreChargeVoltage = PreChargeSwitch * 5.0 / 1023;

//Check if Zeroed Voltage Count is OOR (negative) and set to 0 if negative.  This prevents the voltage counts from wrapping around.
if (VoltageCountsZeroed > 1024) {
  VoltageCountsZeroed = 0;
}

// Calculate Voltage and Pressure from Zeroed Voltage Counts Value
Voltage = VoltageCountsZeroed * 5.0 / 1023;
Pressure = (Voltage)*FullScalePressure / 5;

//Precharge determination logic, if Pressure > 5 bar then set 16 bit pressure output to analog pressure input
if (Pressure > 5) {
  Pressure16bitScaled = Pressure * 51200 / 200;
}
// If precharge switch is activated then set pressure output to 4 bar
else if (PreChargeVoltage > 4.5) {
  Pressure16bitScaled = 1024;  //Corresponds to 4 bar pressure
}
// Otherwise set pressure output to 0
else {
  Pressure16bitScaled = 0;
}

// This causes PKBApplyReleaseRequest to set to 27.
if ((ApplyFlag == 1) && ((millis() - TimeStamp) < 1000)) {
  PKBApplyReleaseRequest = 27;
} else {
  PKBApplyReleaseRequest = 5;
  ApplyFlag == 0;
}

// This causes PKBApplyReleaseRequest to set to 40.  Once 200 ms elapses the request set to 5.
if ((ReleaseFlag == 1) && ((millis() - TimeStamp) < 1000)) {
  PKBApplyReleaseRequest = 40;
} else {
  PKBApplyReleaseRequest = 5;
  ReleaseFlag = 0;
}

//Split 16 bit value into lower and upper bytes to be sent over CAN.
PressureLowByte = (byte)(Pressure16bitScaled & 0x00FF);
PressureHighByte = (byte)((Pressure16bitScaled & 0xFF00) >> 8);

//Read IGN Status signal
IgnStat = digitalRead(23);

//Setting eBooster_CMD
uint8_t eBooster_CMD[7] = { PressureLowByte, PressureHighByte, PKBApplyReleaseRequest, 5, 5, 5, 5 };

//Setting eBooster_Veh_Pwr
if (IgnStat == 0) {
  IgnStatValue = 4;  //sets IgnCmdStat to RUN
} else {
  IgnStatValue = 1;  //sets IgnCmdStat to 1
}



CANFDMessage Receive_Frame_1;
Receive_Frame_1.id = 0x01;
Receive_Frame_1.len = 3;
Receive_Frame_1.ext = false; 

CANFDMessage Send_Frame_1;
Send_Frame_1.id = 0x7;
Send_Frame_1.len = 7;
Send_Frame_1.ext = false;
Send_Frame_1.data[0] = 0;
Send_Frame_1.data[1] = 0; 
Send_Frame_1.data[2] = 0;
Send_Frame_1.data[3] = 0; 
Send_Frame_1.data[4] = 0; 
Send_Frame_1.data[5] = 0;
Send_Frame_1.data[6] = 0; 

CANFDMessage Send_Frame_2;
Send_Frame_2.id = 0x112;
Send_Frame_2.len = 2;
Send_Frame_2.ext = false;
Send_Frame_2.data[0] = IgnStatValue;
Send_Frame_2.data[1] = 0; 

const bool ok = can.tryToSend(Send_Frame_1);
if (ok) {
  Serial.print("Sent: ");
  Serial.println(can.tryToSend(Send_Frame_1));
} else {
  Serial.print ("Send failure: ") ;
  Serial.println(can.tryToSend (Send_Frame_1));
}

const bool ok2 = can.tryToSend(Send_Frame_2);
if (ok2) {
  Serial.print("Sent: ");
  Serial.println(can.tryToSend(Send_Frame_2));
} else {
  Serial.print ("Send failure: ") ;
  Serial.println(can.tryToSend (Send_Frame_2));
}



  if (can.available()) {
  Serial.print("Received: ");
  Serial.println(can.receive(Receive_Frame_1));

}





//memcpy(&ClampForce, &Receive_Frame_1.data[0], 4);

//Receive_Frame_1.data = ntohs(Receive_Frame_1.data);
int32_t ClampForce = ((uint32_t)(Receive_Frame_1.data[3]&0xFF) << 24) | ((uint32_t)(Receive_Frame_1.data[2]&0xFF) << 16) | ((uint32_t)(Receive_Frame_1.data[1]&0xFF) << 8) | ((uint32_t)(Receive_Frame_1.data[0]&0xFF));


Serial.print("Pressure = ");
Serial.println(Send_Frame_1.data[1]);
Serial.print("ClampForce = ");
Serial.println(ClampForce);
Serial.println(Receive_Frame_1.data[0]);
Serial.println(Receive_Frame_1.data[1]);
Serial.println(Receive_Frame_1.data[2]);
//Serial.println(Receive_Frame_1.data[3]);

DACOutVoltage = ClampForce * ClampForce2DynoVoltage;
DACOutVoltageScaled = 500 * DACOutVoltage;

//Set the output value for DAC channel 0, range 0-500
dac.setDACOutVoltage(DACOutVoltageScaled, 0);
dac.store();


//Read KL15 at end of inner while loop to determine if loop should be exited and transmitter rezeroed
KL15 = digitalRead(22);

// send and receive data once every 1 ms

delay(1);

}
}
`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant