Hello,
i have a bigger project.
I already figured how to interface a CAN test board (using the SPI to CAN module when interfacing the test board), which periodically sends out CAN packets.
I am trying to add SD Card module as a datalogger.
Basically:
My board <=> RS232 device
My board <=> CAN module<=CAN test board
?My board <=> Micro SD Card Module?
However the CAN communication stops, when I try to interface the sd card.
Dont mind the RS232 filler, just ignore that…
// demo: CAN-BUS Shield, receive data
#include <mcp_can.h>
#include <SPI.h>
#include <SoftwareSerial.h>
#define rx 7
#define tx 8
//int decMess = 0;
//short unsigned int cursor = 0;
//int pozX[2] = {0,0};
//int pozY[2] = {0,0};
int calcX = 0;
int calcY = 0;
//int *pointerCalcX = &calcX;
//int *pointerCalcY = &calcY;
long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];
unsigned int prectenaHodnota = 0;
short int popelnice = 0;
short int cekamCekam = 0;
const byte zacatek = 0xAA;
const byte konec[4]={0xCC,0x33,0xC3,0x3C};
const byte textTrimr[6]={0x54,0x52,0x49,0x4D,0x52,0x3A};
//text pro SAVE, WRITE, ERASE
const byte textSAVE[4]={0x53,0x41,0x56,0x45};
const byte textWRITE[5]={0x57,0x52,0x49,0x54,0x45};
const byte textERASE[5]={0x45,0x52,0x41,0x53,0x45};
SoftwareSerial kom(rx, tx); // RX, TX
MCP_CAN CAN0(10); // Set CS to pin 10
void printRxCAN();
void clearObr();
void posli1Byte(byte b1);
void posli2Byte(byte b2[]);
void posliZacatek();
void posliKonec();
void posliSekvenci(byte zprava[]);
void posliPrevedeneCislo(unsigned int cislo);
void DebugLED(int pin);
void DebugTRIMR();
void DebugTlacitkaText();
void DebugTlacitka();
int debugDotyk(bool volba);//FALSE ... 0X72, TRUE ... OX73
//int dotykSouradnice(bool volba);//FALSE ... 0X72, TRUE ... OX73
void charCislaNaHexZpravu(char znak);
void vypisCislice(unsigned int cislo);
void setup()
{
Serial.begin(115200);
kom.begin(9600);
CAN0.begin(CAN_500KBPS); // init can bus : baudrate = 500k
pinMode(2, INPUT); // Setting pin 2 for /INT input
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
DebugLED(3);
DebugLED(4);
DebugLED(5);
Serial.println("BOOTOVANI USPESNE");
clearObr();
DebugTlacitka();
DebugTlacitkaText();
DebugTRIMR();
Serial.println("=========================================================");
}
void loop()
{
if(!digitalRead(2)) // If pin 2 is low, read receive buffer
{
CAN0.readMsgBuf(&len, rxBuf); // Read data: len = data length, buf = data byte(s)
rxId = CAN0.getCanId(); // Get message ID
if(rxId == 0x15F772F5){
printRxCAN();
prectenaHodnota = int(rxBuf[0]);//0 az 247
//itoa(prectenaHodnota, bufferProCislo, 10);
vypisCislice(prectenaHodnota);
Serial.print("TRIMR: ");Serial.print(prectenaHodnota);Serial.println();
popelnice = debugDotyk(true);//FALSE ... 0X72, TRUE ... OX73
//if(popelnice != 3){popelnice = dotykSouradnice(true);}
if(popelnice == 1){//1.. ok, 3 .. neni co cist, 2 ... chybne podminky
Serial.print("SOURADNICE: ");Serial.print(calcX);Serial.print(", ");Serial.print(calcY);Serial.println(" [pix]");
if(calcX < 50){
if(( calcY > 0)&&(calcY < 50)){
Serial.println("ZMACKNUTO TLACITKO 1, SAVE");
}
else if(( calcY > 50)&&(calcY < 100)){
Serial.println("ZMACKNUTO TLACITKO 2, WRITE");
}
if(( calcY > 100)&&(calcY < 150)){
Serial.println("ZMACKNUTO TLACITKO 3, ERASE");
}
calcX = 0;calcY = 0;
}
}
Serial.println("=========================================================");
}
}
}
void printRxCAN(){
Serial.print("CAN: ");
Serial.print("ID: ");
Serial.print(rxId, HEX);
Serial.print(" Data: ");
for (int i = 0; i < len; i++) // Print each byte of the data
{
if (rxBuf[i] < 0x10) // If data byte is less than 0x10, add a leading zero
{
Serial.print("0");
}
Serial.print(rxBuf[i], HEX);
Serial.print(" ");
}
Serial.println();
//delay(500);
}
void clearObr(){
byte clr=0x52;
posliZacatek();
posli1Byte(clr);
posliKonec();
}
void DebugLED(int pin){digitalWrite(pin,HIGH);delay(10);digitalWrite(pin,LOW);}
void posliKonec(){for (int i =0; i<sizeof(konec); i++){kom.write(konec[i]);}}
void posliSekvenci(byte zprava[],int delka){for (int i =0; i<delka; i++){posli1Byte(zprava[i]);}}
void posliPrevedeneCislo(unsigned int cislo){
char bufferProCislo[3]={'0','0','0'};
itoa(cislo, bufferProCislo, 10);
if((cislo < 100) && (cislo >=10)){
charCislaNaHexZpravu('0');
charCislaNaHexZpravu(bufferProCislo[0]);
charCislaNaHexZpravu(bufferProCislo[1]);
}
else if(cislo < 10){
charCislaNaHexZpravu('0');
charCislaNaHexZpravu('0');
charCislaNaHexZpravu(bufferProCislo[0]);
}
else{
charCislaNaHexZpravu(bufferProCislo[0]);
charCislaNaHexZpravu(bufferProCislo[1]);
charCislaNaHexZpravu(bufferProCislo[2]);
}
}
void posliZacatek(){kom.write(zacatek);}
void posli1Byte(byte b1){kom.write(b1);}
void posli2Byte(byte b2[]){posli1Byte(b2[0]);posli1Byte(b2[1]);}
void charCislaNaHexZpravu(char znak){
switch(znak){
case ' '://mezera
posli1Byte(0x20);
break;
case '0'://mezera
posli1Byte(0x30);//muyu k tomuhle pricitat offset, ALE tohle je citelnejsi
break;
case '1'://mezera
posli1Byte(0x31);
break;
case '2'://mezera
posli1Byte(0x32);
break;
case '3'://mezera
posli1Byte(0x33);
break;
case '4'://mezera
posli1Byte(0x34);
break;
case '5'://mezera
posli1Byte(0x35);
break;
case '6'://mezera
posli1Byte(0x36);
break;
case '7'://mezera
posli1Byte(0x37);
break;
case '8'://mezera
posli1Byte(0x38);
break;
case '9'://mezera
posli1Byte(0x39);
break;
default:
delay(1);
}
}
void vypisCislice(unsigned int cislo){//3mistny cislo
byte poziceXNum[]={0x00,0xFF};
byte poziceYNum[]={0x00,0xFF};
byte zluta[]={0xFC,0x00};
byte modra[]={0x00,0x1F};
////////////////////////////////////////////////////////////////////////////////////////
posliZacatek();
posli1Byte(0x98);//ID
posli2Byte(poziceXNum);
posli2Byte(poziceYNum);
posli1Byte(0x00);//00
posli1Byte(0xC1);//styl zobrazeni
posli1Byte(0x05);//ID KNIHOVNY
posli2Byte(zluta);
posli2Byte(modra);
posli1Byte(0x00);
posliPrevedeneCislo(cislo);
posliKonec();
}
void DebugTRIMR(){
byte poziceX[]={0x00,0xFF};
byte poziceY[]={0x00,0xCF};
byte zluta[]={0xFC,0x00};
byte modra[]={0x00,0x1F};
posliZacatek();
posli1Byte(0x98);//ID
posli2Byte(poziceX);
posli2Byte(poziceY);
posli1Byte(0x00);//00
posli1Byte(0xC1);//styl zobrazeni
posli1Byte(0x05);//ID KNIHOVNY
posli2Byte(zluta);
posli2Byte(modra);
posli1Byte(0x00);
posliSekvenci(textTrimr,6);
posliKonec();
}
int debugDotyk(bool volba){//FALSE ... 0X72, TRUE ... OX73
int decMess = 0;
bool spravnyStart = false;
short unsigned int cursor = 1;
int pozX[2] = {0,0};
int pozY[2] = {0,0};
Serial.print("RS232: ");
while(true){
decMess = int(kom.read());
switch(decMess){
case 170:
//Serial.print("xAA ");
spravnyStart = true;
cursor +=1;
break;
case 204:
calcX=pozX[0]*16*16 + pozX[1];
calcY=pozY[0]*16*16 + pozY[1];
//*pointerCalcX = funcCalcX;
//*pointerCalcY = funcCalcY;
/*
if((calcX < 305)&&(calcY < 230)){DebugLED(10);}
else if((calcX > 305)&&(calcY < 230)){DebugLED(9);}
else if((calcX < 305)&&(calcY > 230)){DebugLED(11);}
else if((calcX > 305)&&(calcY > 230)){DebugLED(12);}
Serial.print("()()zaznam pozice X= ");Serial.print(pozX[0]);Serial.print(" ");Serial.print(pozX[1]);//zaznam x
Serial.print(" zaznam pozice Y= ");Serial.print(pozY[0]);Serial.print(" ");Serial.print(pozY[1]);//zaznam y
Serial.print(" pozice X= ");Serial.print(calcX);Serial.print(" pix, ");//kalkulace x
Serial.print("pozice Y= ");Serial.print(calcY);Serial.print(" pix()() ");//kalkulace y
*/
if(spravnyStart == false){Serial.println("WRONG"); cursor = 0; cekamCekam = 0; return 2;}
Serial.print("xCC ");
cursor +=1;
break;
case 60:
if(spravnyStart == false){Serial.println("WRONG"); cursor = 0; cekamCekam = 0; return 2;}
Serial.println("x3C");
cursor = 1;
decMess = -1;
cekamCekam = 0;
DebugLED(3); return 1; //vse ok
break;
case 195:
if(spravnyStart == false){Serial.println("WRONG"); cursor = 0; cekamCekam = 0; DebugLED(4); return 2; }
Serial.print("xC3 ");
cursor +=1;
break;
case 51:
if(spravnyStart == false){Serial.println("WRONG"); cursor = 0; cekamCekam = 0; DebugLED(4); return 2; }
Serial.print("x33 ");
cursor +=1;
break;
case 114:
if((volba == true)||(spravnyStart == false)){Serial.println("WRONG"); cursor = 0; cekamCekam = 0; DebugLED(4); return 2; }//chci 0x73
Serial.print("xAA x72 ");
cursor +=1;
//pozX = int(kom.read())*16*16 + int(kom.read())*16;
//pozY = int(kom.read())*16*16 + int(kom.read())*16;
//Serial.print("pozice X = ");Serial.print(pozX);
//Serial.print(", pozice Y = ");Serial.print(pozY);Serial.print(" ");
break;
case 115:
if((volba == false)||(spravnyStart == false)){Serial.println("WRONG"); cursor = 0; cekamCekam = 0; DebugLED(4);return 2; }//chci 0x72
Serial.print("xAA x73 ");
cursor +=1;
break;
case -1://SKIP
cekamCekam += 1;
if(cekamCekam == 10){Serial.println("NULL");cekamCekam = 0; DebugLED(5); return 3; }
break;
default:
if(spravnyStart == false){Serial.println("WRONG"); cursor = 0; cekamCekam = 0; DebugLED(4);return 2;}
Serial.print(decMess);
if(cursor == 3){pozX[0] = decMess;}
if(cursor == 4){pozX[1] = decMess;}
if(cursor == 5){pozY[0] = decMess;}
if(cursor == 6){pozY[1] = decMess;}
cursor +=1;
Serial.print(" ");
break;
}
}
}
void DebugTlacitka(){//xx xx yy yy ...4 byty
byte souradniceA[4]={0x00,0x00,0x00,0x00};//0 0 ... pix
byte souradniceB[4]={0x00,0x32,0x00,0x32};//50 50
byte souradniceC[4]={0x00,0x00,0x00,0x32};//0 50
byte souradniceD[4]={0x00,0x32,0x00,0x64};//50 100
byte souradniceE[4]={0x00,0x00,0x00,0x64};//0 100
byte souradniceF[4]={0x00,0x32,0x00,0x96};//50 150
posliZacatek();//tlacitko 1
posli1Byte(0x59);
posliSekvenci(souradniceA,4);
posliSekvenci(souradniceB,4);
posliKonec();
posliZacatek();//tlacitko 2
posli1Byte(0x59);
posliSekvenci(souradniceC,4);
posliSekvenci(souradniceD,4);
posliKonec();
posliZacatek();//tlacitko 3
posli1Byte(0x59);
posliSekvenci(souradniceE,4);
posliSekvenci(souradniceF,4);
posliKonec();
}
void DebugTlacitkaText(){
byte souradniceX[2]={0x00,0x40};//50 50
byte souradniceY1[2]={0x00,0x00};//50 50
byte souradniceY2[2]={0x00,0x32};//50 100
byte souradniceY3[2]={0x00,0x64};//50 150
byte zluta[]={0xFC,0x00};
byte modra[]={0x00,0x1F};
//const byte textSAVE[4]={0x53,0x41,0x56,0x45};
//const byte textWRITE[5]={0x57,0x52,0x49,0x54,0x45};
//const byte textERASE[5]={0x45,0x52,0x41,0x53,0x45};
//pro rzchle prekopirovani
posliZacatek();//SAVE
posli1Byte(0x98);//ID
posli2Byte(souradniceX);
posli2Byte(souradniceY1);
posli1Byte(0x00);//00
posli1Byte(0xC1);//styl zobrazeni
posli1Byte(0x05);//ID KNIHOVNY
posli2Byte(zluta);
posli2Byte(modra);
posli1Byte(0x00);
posliSekvenci(textSAVE,4);
posliKonec();
posliZacatek();//WRITE
posli1Byte(0x98);//ID
posli2Byte(souradniceX);
posli2Byte(souradniceY2);
posli1Byte(0x00);//00
posli1Byte(0xC1);//styl zobrazeni
posli1Byte(0x05);//ID KNIHOVNY
posli2Byte(zluta);
posli2Byte(modra);
posli1Byte(0x00);
posliSekvenci(textWRITE,5);
posliKonec();
posliZacatek();//ERASE
posli1Byte(0x98);//ID
posli2Byte(souradniceX);
posli2Byte(souradniceY3);
posli1Byte(0x00);//00
posli1Byte(0xC1);//styl zobrazeni
posli1Byte(0x05);//ID KNIHOVNY
posli2Byte(zluta);
posli2Byte(modra);
posli1Byte(0x00);
posliSekvenci(textERASE,5);
posliKonec();
}
This is my code for now, a LOT of it is just RS232. But I am adding the code for the sake of being open.
I got a standard setup of MOSI (D11), MISO (D12), CS (D10) and SCK (D13) to run CAN, I have a display on pins D7 & D8 (RS232).
At this point I am afraid, that I will have to utilise a separate Atmega 328P board just to use it with I2C and have the second board manage the SD Card.
In this case, is it possible to run CAN comm and also log my data into SD card with Arduino Nano?
If possible, could you please direct in right direction?
Example code, reference sites, general knowledge, anything will be helpful or your questions of anything unclear about my question or project.
I am imagining I will use the same SCK, MISO and MOSI pins for the SD card module, but a different CS pin, but that is as far I can imagine myself solving my issue.
SPI is very new to me and I guess this is the most direct way for me to figure out my issue, thanks to you.
Thank you in advance.