Hi,
I have an Uno receiving data from an Engine ECU via a CANBUS shield and I now want to output that data onto some OLEDs. I am using the excellent u8glib library for the displays and have put together a sketch which gets me the data that I want, however, something about it is slowing the CANBUS comms down! This means that the displays are sometimes taking half a minute or more to update to newer information.
I have done some investigating using the serial monitor and have established that it's not the displays that are at fault - as soon as they get the new info, they display it. It's just that the new info is slow to arrive from the CANBUS. Also, by running just the CANBUS code, the RX led on the shield blinks quickly and I get new data in straight away at the serial monitor, indicating that it's working correctly. When trying to run the CANBUS & OLED codes combined, the RX LED is on solid (I suspect flashing too fast for my eyes to detect) and the serial monitor is slow to scroll, with the data taking a long time to update.
A snippet of the code:
void ct() {
u8g.setFont(u8g_font_helvB24n);
u8g.setScale2x2();
u8g.setPrintPos( 0, 24);
u8g.print(CT);
u8g.undoScale();
u8g.setFont(u8g_font_helvB10);
u8g.setPrintPos( 0, 61);
u8g.print("Coolant");
u8g.setPrintPos( 112, 61);
u8g.print((char)176);
u8g.setPrintPos( 118, 61);
u8g.print("C");
}
void at() {
u8g.setFont(u8g_font_helvB24n);
u8g.setScale2x2();
u8g.setPrintPos( 0, 24);
u8g.print(AT);
u8g.undoScale();
u8g.setFont(u8g_font_helvB10);
u8g.setPrintPos( 0, 61);
u8g.print("Intake");
u8g.setPrintPos( 112, 61);
u8g.print((char)176);
u8g.setPrintPos( 118, 61);
u8g.print("C");
}
void draw_gauge1(void) {
switch(gauge1counter) {
case 0: boost(); break;
case 1: tps(); break;
case 2: batt(); break;
case 3: op(); break;
case 4: ct(); break;
case 5: at(); break;
case 6: ot(); break;
}
}void picture1()
{
u8g.firstPage();
do {
draw_gauge1();
} while( u8g.nextPage() );
}void counters(void) {
int reading1 = digitalRead(19);
if (reading1 != lastgauge1ButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading1 != gauge1ButtonState) {
gauge1ButtonState = reading1;
if (gauge1ButtonState == HIGH) {
gauge1counter++;
if (gauge1counter >=7)
gauge1counter = 0;
}
}
}
lastgauge1ButtonState = reading1;
}
void setup(void) {
pinMode(18, INPUT);
pinMode(19, INPUT);
CAN0.begin(CAN_1000KBPS);
Serial.begin(115200);
pinMode(2, INPUT);
// flip screen, if required
// u8g.setRot180();
}
void loop(void) {
if(!digitalRead(2))
{
CAN0.readMsgBuf(&len, rxBuf);
rxId = CAN0.getCanId();
}
if (rxId == 4096) {
RPM1 = (rxBuf[0] * 100);
RPM2 = (rxBuf[1]);
MAP1 = (rxBuf[2] * 256);
MAP2 = (rxBuf[3]);
OP1 = (rxBuf[4] * 100);
OP2 = (rxBuf[5]);
TPS = (rxBuf[6]);
}
if (rxId == 4097) {
AFR1 = (rxBuf[4]);
AFR2 = (rxBuf[5]);
}
if (rxId == 4099) {
AT = (rxBuf[0] - 40);
CT = (rxBuf[1] - 40);
OT = (rxBuf[2] - 40);
BAT = (rxBuf[7] / 11.0);
}
RPM = RPM1 + RPM2;
MAP = (MAP1 + MAP2) - 1013;
Boost = MAP * 0.0145;
Vac = (MAP * 0.0295);// - 29.92;
{
picture1();
counters();
}
}
If I comment out picture1(); near the bottom then the CANBUS code alone runs fine. I actually have 7 data sets that I want to display and am also using 2 OLEDs. They control independently of each other OK and toggle through the 7 different options instantaneously when the appropriate button is pressed. I didn't include every last bit of my sketch as I thought it would just make an unnecessary mess of duplicated code!
So to sum up, the CANBUS part is fine on it's own and the OLEDs display correctly on their own, but my attempt to amalgamate the two results in the CANBUS running slow - can anyone see where the problem lies? Many thanks!