adamtheone / canDrive

Tools for hacking your car
https://www.youtube.com/playlist?list=PLNiFaO8hU1z0o_6DSxk-jcVAM3UCUR-pY
MIT License
544 stars 147 forks source link

possibility to log on an SD card #41

Open superpeg00 opened 1 year ago

superpeg00 commented 1 year ago

hello, i succesfully filtered the CAN data I needed and now i would like con log them on an sd card; i bought an sd logger shield https://amzn.eu/d/3nkAmTf but the shield cs pin is connected to the pin 10, the same as the MCP2515. I can write on the sd only if the CAN communication is not active; if I start logging data from CAN i can not communicate with the sd card, i thing because the spi line is occupied by arduino and MCP2515. My idea so is to log the data, than stop the can communication in order to free the spi line and write data on sd, than re-active the can communication and doing this every loop; I tried using CAN.end(); or CAN.sleep(); but nothing changed. is my idea completely wrong or it could work? thank you very much.

superpeg00 commented 1 year ago

In order to make things more clear this is the code, the error is in the last if-else cycle; on the serial monitor i recive "error opening Datalog.txt"

include

include

include

void setup() { //setup CAN

Serial.begin(9600); while (!Serial);

//setup parte CAN

Serial.println("CAN Receiver");

// start the CAN bus at 500 kbps if (!CAN.begin(500E3)) { Serial.println("Starting CAN failed!"); //while (1); } CAN.filter(0x518);

//setup SD Serial.begin(9600); while (!Serial) { ; }

Serial.print("Initializing SD card...");

// see if the card is present and can be initialized: if (!SD.begin(10)) { Serial.println("Card failed, or not present"); // don't do anything more: while (1); } Serial.println("card initialized.");

}

void loop() {

int packetSize = CAN.parsePacket(), i=0;
float Vlamb=0, lamb=0;
Vlamb=analogRead(A0);

float pack[8];

//Serial.print("packet with id 0x");
//Serial.print(CAN.packetId(), HEX);
//Serial.print(" and length ");
//Serial.println(packetSize);
//Serial.println();

//salvo i valori del pacchetto ricevuto nella matrice pack
      while (CAN.available()) {
    //Serial.print(CAN.read(), HEX);
    pack[i]=CAN.read();
    i=i+1;    
  }
Serial.println(); 
//stampo sul seriale i valori contenuti nel pacchetto ricevuto
for(i=0;i<8;i++) {
  Serial.print(pack[i]);
} 
Serial.println();

float rpm = ((pack[1] * 256.0) + pack[0]) / 4.0; //creo una variabile rpm che contiene rpm

Serial.print("Engine RPM = "); Serial.println(rpm); Serial.print("lamb = "); lamb=Vlamb/3; Serial.println(lamb);

// inizializzo stringa per raccogliere i dati

String dataString = "";

//popolo la stringa

int sensor = analogRead(A0); dataString += String(sensor);

File dataFile = SD.open("datalog.txt", FILE_WRITE);

// controllo sul file if (dataFile) { dataFile.println(dataString); dataFile.close(); // print to the serial port too: Serial.println(dataString); }

else { Serial.println("error opening datalog.txt"); //here is it the error }

delay(500); }

adamtheone commented 1 year ago

Hello! I'd suggest you to take a deep dive into SPI communication. You might need to change one or two things in the lower layers, but your setup (parallel MCP2515 and SDCard) is completely doable. You can just choose another pin as the SPI CS pin. That pin does nothing special, but goes low before the transmission, and goes high right after it. You can even control it yourself from the main logic. One thing to keep in mind: storing data to the SDCard will take some time, and meanwhile, you'll not be able to receive messages from the MCP2515 (because Arduino only has 1 SPI peripheral if I'm not mistaken).