Hi guys,
So here what I'm trying to do. I'm using one Arduino Uno (the master one) to read values of 2 MPU6050 via i2c. Then, I send a command through CAN bus using MCP2515 shields to a motor controller.
Then, I have a second Arduino Uno (slave) that also has a CAN bus shield and I use it to write data on an SD card. I use a push button to switch the state variable. Here's my problem:
I want to write data on the SD card coming from the motor controller and the data registered by the master Arduino. Requesting data to the motor controller is an easy task, because I send a CAN message with the RTR bit == 1 and I receive a answer with the desired data.
However, when I want to get data from the master, I don't know how to implement the RTR protocol. Hence, I simply always send the data from the sensors over the CAN bus and the slave will capt the data when it needs it.
The problem occurs in the readRegister() void. I'm trying to make sure I read the right message in the right order to make sure I have a consistent file at the end. This part is now no longer working and I have a problem specifically with this part :
(infoEnregistrer[i] == canId)
I simply want to confirm that the CAN id is the same as the one I want to write to my SD. When the code was working, I was getting the desired CAN id but I was still stuck in the While loop...
To be honest, it's been 2 days I'm on this problem and I have no clue why it's not working nor how to correct it.
#include "Wire.h"
//***********************************************************//
// For Arduino MCP2515 Hat:
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 10; // pin 9
const int CAN_INT_PIN = 2;
#include "mcp2515_can.h"
mcp2515_can CAN(SPI_CS_PIN); // set CS pin
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x20, 16, 2);
byte axisId = 0x01 << 5U; // Result: 0x020
unsigned long periode = 60; // période d'aquisition de données
unsigned long delais; //Utilisé pour storer millis()
unsigned long timer;
unsigned long affichage = 0; // pour diminuer le refresh rate du LCD
unsigned long affichage2 = 0; // pour diminuer le refresh rate du LCD
unsigned long affichage3 = 0; // pour diminuer le refresh rate du LCD
/**********Play/pause datalogger**************/
const byte interruptPin = 3;
volatile byte state = LOW;
boolean ledState = LOW; // ledState used to set the LED
const int ledLight = 7; // the number of the LED pin
const int ledRead = 6; // pin pour play/pause enregistrement
unsigned long attendre = 0; // delais pour empĂŞcher 8 fois la meme lecture du bouton pour enregistrement
byte infoEnregistrer[] = {0x037, 0x029, 0x035};//, 0x049}; // voltage, vitesse, température, angle
byte lastId;
#include <SdFat.h>
SdFat sd;
SdFile myFile;
char filename[] = "test000.txt";
int i = 0;
int j = 0;
bool flag = true;
/*************************Debut du programme*******************************************/
void setup() {
Wire.begin();
lcd.init();
lcd.backlight();
lcd.setCursor(0,0);
while (!Serial) ; // wait for Arduino Serial Monitor to open
Serial.begin(115200);
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k and clock 8MHz for Odrive Pro MCP_8MHz
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL_PORT_MONITOR.println("CAN init OK.");
lcd.setCursor(0,0);
lcd.print("CAN init OK.");
if (!sd.begin(4, SPI_FULL_SPEED)) sd.initErrorHalt();
while (sd.exists(filename)){
i ++;
sprintf(filename, "test%03i.txt", i);
}
Serial.print(filename);
if (!myFile.open(filename, FILE_WRITE)) { ;//O_RDWR |
sd.errorHalt("opening test.txt for write failed");
}
SERIAL_PORT_MONITOR.println("SD init OK.");
lcd.setCursor(0,1);
lcd.print("SD:");
lcd.setCursor(0,9);
lcd.print(filename);
pinMode(ledLight, OUTPUT);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), blink, FALLING);
delay(5000);
delais=millis();
timer = millis();
}
void loop() {
if ((millis()-delais)>periode){
voltage();
vitesse();
temperature();
//getAngleCAN();
digitalWrite(ledLight, state);
delais = millis();
}
}
void blink() {
state = !state;
}
void readRegister(char *info, bool deux, byte filter){ // si le get message retourne 2 données différentes/ filter : savoir quel message est renvoyer
if (state == HIGH){
lcd.setCursor(13,1);
lcd.print("REC");
unsigned char len = 0;
unsigned char buf[8];
float y,z;
if (CAN_MSGAVAIL == CAN.checkReceive()) { // check if data coming
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf
byte canId = CAN.getCanId(); //unsigned long
for (i = 0; sizeof(infoEnregistrer)-1; i++){
j=0;
flag = true;
while (flag == true) {
CAN.sendMsgBuf(infoEnregistrer[i], 0, 1, 8, 0, false);
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf
byte canId = CAN.getCanId(); //unsigned long
if (infoEnregistrer[i] != canId){
Serial.print("obtenu :");
Serial.print(canId);
Serial.print(", demandé:");
Serial.print(infoEnregistrer[i]);
Serial.print(", ");
Serial.println(infoEnregistrer[i] == canId);
}
else{
Serial.print("obtenu :");
Serial.print(canId);
Serial.print(", demandé:");
Serial.print(infoEnregistrer[i]);
Serial.print(", ");
Serial.println(infoEnregistrer[i] == canId);
flag == false;
break;
}
}
SERIAL_PORT_MONITOR.println(canId);
Serial.print(canId);
Serial.println(" Victoire");
union u_tag {
byte b[4];
float fval;
} u;
u.b[0] = buf[0];
u.b[1] = buf[1];
u.b[2] = buf[2];
u.b[3] = buf[3];
y = u.fval;
if (deux ==1){
u.b[0] = buf[4];
u.b[1] = buf[5];
u.b[2] = buf[6];
u.b[3] = buf[7];
z=u.fval;
}
if (canId == 0x037 && (millis()-affichage)>500){ //voltage
lcd.setCursor(0,0);
lcd.print(String(y) + " V ");
affichage = millis();
}
else if (canId == 0x035 && (millis()-affichage3)>500){ //temp
lcd.setCursor(0,1);
lcd.print(String(y) + " C ");
affichage3 = millis();
}
else if (canId == 0x049 && (millis()-affichage3)>500){ //temp
lcd.setCursor(9,0);
lcd.print(String(y-z) + " deg ");
affichage3 = millis();
}
writeSD(y,z);
}
}
}
else if (state == LOW){
lcd.setCursor(0,0);
lcd.print("Blanc: reset ");
lcd.setCursor(0,1);
lcd.print("Bleu: REC ");
}
}
void getAngleCAN(){
readRegister("lecture acceleros", 1, 0x049);
myFile.println();
myFile.sync();
}
void voltage(){
byte getVBus = 0x017; // Get_Vbus_Voltage_Current
byte getVBusId = axisId | getVBus; // Result: 0x037
CAN.sendMsgBuf(getVBusId, 0, 1, 8, 0, true);
readRegister("voltage & ampère", 1, getVBusId);
}
void vitesse(){
byte getVel = 0x009; // Get_Encoder_Estimates
byte getVelId = axisId | getVel; // Result: 0x029
CAN.sendMsgBuf(getVelId, 0, 1, 8, 0, true);
readRegister("position & vitesse", 1, getVelId);
}
void temperature(){
byte getTemp = 0x015; // Get_Temperature
byte getTempId = axisId | getTemp; // Result: 0x035
CAN.sendMsgBuf(getTempId, 0, 1, 8, 0, true);
readRegister("temperature", 0, getTempId);
}
void writeSD(float y, float z) {
myFile.print(y);
myFile.print(",");
myFile.print(z);
myFile.print(",");
}
Thanks in advance !