I am trying to communicate arduino uno with CAN bus using MCP2515 shield. Data sending and receiving both things are done. Whatever data received is displayed on LCD. CAN bus receive is done using interrupt of timer1 and LCD updating using interrupt of timer2. I think LCD does not get enough time for updating hence garbage data appears on LCD. So please suggest me solution so that I can get Both CAN communication and LCD updation. I am posting my code for your reference.
#include <Wire.h>
#include <CAN.h>
#include <Adafruit_ADS1015.h>
#include <EEPROM.h>
#include <LiquidCrystal.h>
Adafruit_ADS1115 ads; /* Use this for the 16-bit version */
int timer2_counter;
int timer1_counter;
uint16_t adc0;
uint8_t adch,adcl;
char receive;
uint8_t dlc = 0;
int addr = 0;
long sensorValue = 0; // the sensor value
float rpm;
uint16_t count = 0;
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup(void)
{
Serial.begin(9600);
while (!Serial);
// initialize timer1
noInterrupts(); // disable all interrupts
//---------------------TIMER_1---------------------------------------//
TCCR1A = 0;
TCCR1B = 0;
//timer1_counter = 64930; // preload timer 65536-16MHz/256/100Hz 10ms 64911
//timer1_counter = 64911; // preload timer 65536-16MHz/256/100Hz
timer1_counter = 64286; // preload timer 65536-16MHz/256/50Hz
// timer1_counter = 34286; // preload timer 65536-16MHz/256/2Hz
//timer1_counter = 62411; // preload timer 65536-16MHz/256/20Hz 100msec
TCNT1 = timer1_counter; // preload timer
TCCR1B |= (1 << CS12); // 256 prescaler
TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt
//Setup Timer2 to fire every 1ms
TCCR2B = 0x00; //Disbale Timer2 while we set it up
TCNT2 = 130; //Reset Timer Count to 130 out of 255
TIFR2 = 0x00; //Timer2 INT Flag Reg: Clear Timer Overflow Flag
TIMSK2 = 0x01; //Timer2 INT Reg: Timer2 Overflow Interrupt Enable
TCCR2A = 0x00; //Timer2 Control Reg A: Wave Gen Mode normal
TCCR2B = 0x05; //Timer2 Control Reg B: Timer Prescaler set to 128
interrupts(); // enable all interrupts
Serial.println("CAN Sender");
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("DYNALEC CONTROLS");
ads.setGain(GAIN_ONE); // 1x gain +/- 4.096V 1 bit = 2mV 0.125mV
ads.begin();
// start the CAN bus at 500 kbps
if (!CAN.begin(500E3)) {
Serial.println("Starting CAN failed!");
while (1);
}
}
ISR(TIMER2_OVF_vect)
{
TCNT2 = timer2_counter; // preload time
count++;
if(count >= 20000)
{
Serial.println("LCD");
lcd_write();
count = 0;
}
}
ISR(TIMER1_OVF_vect) // interrupt service routine
{
TCNT1 = timer1_counter; // preload time
if(dlc == 1)
{
Serial.print("packet with id 0x");
Serial.print(CAN.packetId(), HEX);
dlc = 0;
CAN.beginExtendedPacket(0x0C00DAEF); //(PGN-0 Priority-3 src Addr- EF Dest Addr-DA)
CAN.write(0x00);
CAN.write(adch);
CAN.write(adcl);
CAN.write(0x00);
CAN.write(0x00);
CAN.write(0x00);
CAN.write(0x00);
CAN.write(0x00);
CAN.endPacket();
Serial.println(" ");
}
else{
CAN.beginExtendedPacket(0x0C00DAEF); //(PGN-0 Priority-3 src Addr- EF Dest Addr-DA)
CAN.write(0xFF);
CAN.write(adch);
CAN.write(adcl);
CAN.write(0xFF);
CAN.write(0xFF);
CAN.write(0xFF);
CAN.write(0xFF);
CAN.write(0xFF);
CAN.endPacket();
Serial.println(" ");
}
}
//------------------------------------while_loop-------------------------------------------//
void loop(void)
{
//lcd_write();
read_ads();
read_can();
calibration();
}
// ------------------------------lcd_write---------------------------------------------------//
void lcd_write(void)
{
noInterrupts();
//Serial.println("LCD");
lcd.setCursor(0, 1);
delay(10);
lcd.print("RPM: ");
lcd.print(rpm);
delay(10);
interrupts();
}
//--------------------------ads_read--------------------------------------------------------//
void read_ads(void)
{
adc0 = ads.readADC_SingleEnded(0);// 10v = 64255 = 8031.875 max value speed. adjust 10v = 32127 counts.
adc0 = adc0 * 2;
sensorValue = adc0 - offset;
sensorValue = sensorValue * slope;
sensorValue = sensorValue / 10000;
Serial.println(sensorValue);
rpm = sensorValue * 0.125;
Serial.println("RPM:");
Serial.println(rpm);
/adch = adc0 >> 8;
adcl = adc0 & 0x00FF;
Serial.print("AIN0: "); Serial.println(adc0);
Serial.println(adch);
Serial.println(adcl);/
}
//--------------------------------------can_read-----------------------------------------------------//
void read_can(void)
{
// try to parse packet
int packetSize = CAN.parsePacket();
if (packetSize) {
// received a packet
Serial.print("Received ");
if (CAN.packetExtended()) {
Serial.print("extended ");
}
if (CAN.packetRtr()) {
// Remote transmission request, packet contains no data
Serial.print("RTR ");
}
Serial.print("packet with id 0x");
Serial.print(CAN.packetId(), HEX);
if (CAN.packetRtr()) {
Serial.print(" and requested length ");
Serial.println(CAN.packetDlc());
} else {
Serial.print(" and length ");
Serial.println(packetSize);
// only print packet data for non-RTR packets
while (CAN.available()) {
Serial.print(CAN.read(),HEX);
}
Serial.println();
}
if((CAN.packetDlc() == 3) && (CAN.packetId() == 0x3AEF))
{
dlc = 1;
}
Serial.println();
}
}