Hi everyone,
I'm working on a project where I'm trying to read live data from a Honda motorcycle ECU using an AVR microcontroller via UART, and display some of the values (like RPM, temperature, etc.) on a 16x2 I2C LCD using the LiquidCrystal_I2C library. Inspired by Gonzos
I am still working on the code, therefore some of the variables are not used yet.
If needed i can add the usart header file i am using to this post!
Everything works fine individually:
- The LCD works perfectly in a standalone test sketch.
- The UART communication with the ECU works flawlessly on its own.
However, as soon as I add the line screen.init(); in the full project, the program blocks right there. Nothing proceeds past that point. No UART traffic, no display updates, no activity.
Below is the full code. I’ve translated the original variable names and comments from German to English for clarity. I'd really appreciate if someone can spot what's causing the conflict — I'm wondering if something in the USART setup is interfering with I2C.
Thanks in advance!
#include "USART.h"
#include <util/delay.h>
/*
#include <U8g2lib.h>
#include <SPI.h>
#include <Wire.h>
*/
#include <LiquidCrystal_I2C.h>
// Handlebar buttons (Left & Right)
#define Pin_BtnL 0
#define Pin_BtnR 1
// Chain oiler output
#define PinOILER 5
#define PinOILER_on PORTB |= (1 << PinOILER)
#define PinOILER_off PORTB &= ~(1 << PinOILER)
// UART RX / TX
#define PinRX 0
#define PinTX 1
#define PinTX_on PORTB |= (1 << PinTX)
#define PinTX_off PORTB &= ~(1 << PinTX)
// LCD
LiquidCrystal_I2C screen(0x27, 8, 2);
int main() {
// Set pin directions
DDRB &= ~(1 << Pin_BtnL); // Input
DDRB &= ~(1 << Pin_BtnR); // Input
DDRD &= ~(1 << PinRX); // Input (UART Receive)
DDRD |= (1 << PinTX); // Output (UART Transmit)
// Enable internal pullups for BtnL & BtnR
PINB &= ~(1 << Pin_BtnL);
PINB &= ~(1 << Pin_BtnR);
// --- Startup animation ---
// Initialize LCD
screen.init(); // ### <-- CODE HANGS HERE ###
// Wake up ECU
PinTX_on;
_delay_ms(70);
PinTX_off;
_delay_ms(120);
USARTInit(0, 10400, 1, 0, 1, 0); // Start UART
for (uint8_t i = 0; i <= 3; i++) {
uint8_t Hex[] = {0xFE, 0x04, 0xFF, 0xFF};
USARTTransmit(0, Hex[i]);
}
_delay_ms(200);
for (uint8_t i = 0; i <= 4; i++) {
uint8_t Hex[] = {0x72, 0x05, 0x00, 0xF0, 0x99};
USARTTransmit(0, Hex[i]);
}
// Make data arrays globally available
uint8_t Data_11[20];
uint8_t Data_D1[10];
while (1) {
// --- Read values ---
// Request table 11 from 00 to 16
for (uint8_t i = 0; i <= 6; i++) {
uint8_t Hex[] = {0x72, 0x07, 0x72, 0x11, 0x00, 0x16, 0xEE};
USARTTransmit(0, Hex[i]);
}
// Store incoming values
for (uint8_t i = 0; i <= 20; i++) {
while (!USARTCharReceived(0));
Data_11[i] = USARTReceive(0);
}
// Request table D1 from 00 to 06
for (uint8_t i = 0; i <= 6; i++) {
uint8_t Hex[] = {0x72, 0x07, 0x72, 0xD1, 0x00, 0x06, 0x3E};
USARTTransmit(0, Hex[i]);
}
// Store incoming values
for (uint8_t i = 0; i <= 10; i++) {
while (!USARTCharReceived(0));
Data_D1[i] = USARTReceive(0);
}
// --- Convert values ---
uint16_t RPM = (Data_11[5] << 8) | Data_11[6];
float TPS_Volt = Data_11[7] * (5.0 / 256.0);
float TPS_Percent = Data_11[8] / 16.0;
float ECT_Volt = Data_11[9] * (5.0 / 256.0);
int8_t ECT_temp = Data_11[10] - 40;
float IAT_Volt = Data_11[11] * (5.0 / 256.0);
int8_t IAT_temp = Data_11[12] - 40;
float MAP_Volt = Data_11[13] * (5.0 / 256.0);
uint8_t MAP_kPa = Data_11[14];
float Batt_Volt = Data_11[17] / 10.0;
uint8_t Speed = Data_11[18];
// Display logic would go here
}
}