I2C not working (Blue Pill, HD44780)
Posted: Sun Oct 29, 2023 9:55 am
Hi,
I can't make the simple "Hello, World" show on 16x2 LCD monitor. First, what seems to be OK:
The HD44780 + PCF8574, factory soldered. It works normally with ESP32 processor dangling on the USB cable plugged into the same laptop's USB port. The internal PCF8574 pull-up resistors measure at 4.5k, which is probably slightly better than just OK.
Arduino IDE 2 settings:
Board: "Generic STM32F1 series"
Port: "/dev/tty/ACM0" (grayed out)
Debug symbols and core logs: "None"
Optimize: "Smallest (-Os default)"
Board part number: "BluePill F103C8"
C Runtime Library: "Newlib Nano (default)"
Upload method: "HID Bootloader 2.2"
USB support (if available): "CDC (generic 'Serial' supersede U(S)ART)"
U(S)ART support: "Enabled (generic 'Serial')"
USB speed (if available): "Low/Full Speed"
Breadboard connections:
STM32F103C8T6 PCF8574
GND --- GND
5V --- VCC
B6 --- SCL
B7 --- SDA
The only sketch to show any consistency is the I2CScanner:
Scanning...
I2C device found at address 0x27 !
done
Which is exactly what I'd expect.
All the libraries like LiquidCrystalI2C just won't work, so I tried Wire-only solution, just to look at error messages.
#include <Wire.h>
void WirebeginTransmission() {
Wire.beginTransmission(0x27);
}
const char* DecodeEndTransmission(unsigned errorCode) {
switch (errorCode) {
case 1: return "data too long to fit in transmit buffer";
case 2: return "received NACK on transmit of address";
case 3: return "received NACK on transmit of data";
case 4: return "other error";
case 5: return "timeout";
default: return (errorCode ? "UNKNOWN" : "ZERO");
}
}
void WireendTransmission(char* msg) {
unsigned code = Wire.endTransmission();
if (code > 0 && msg != NULL) {
Serial.printf("endTransmission: \"%s\" %s\n", msg, DecodeEndTransmission(code));
}
}
void setup() {
Serial.begin(9600);
while(!Serial);
Wire.begin();
Wire.setClock(400000);
WirebeginTransmission();
Wire.write(0x01); // Clear display
WireendTransmission("setup");
}
unsigned count = 0;
void loop() {
Serial.printf(">>%d<<\n", count++);
WirebeginTransmission();
Wire.write(0x80); // Set cursor to the first line
Wire.write("Hello, World!");
WireendTransmission("loop");
delay(1000);
}
I can only see endTransmission: "loop" other error; if I comment out all the Wire.write() inside loop(), I can see endTransmission: "loop" received NACK on transmit of address. Besides, the display doesn't get reliably cleared in spite of the alleged success.
It looks like power supply problem; I even plugged the programmed assembly into USB power supply 1500mA, but is won't show any difference. I tried different Wire.setClock() values, including the default. No difference.
What else can I check?
I can't make the simple "Hello, World" show on 16x2 LCD monitor. First, what seems to be OK:
The HD44780 + PCF8574, factory soldered. It works normally with ESP32 processor dangling on the USB cable plugged into the same laptop's USB port. The internal PCF8574 pull-up resistors measure at 4.5k, which is probably slightly better than just OK.
Arduino IDE 2 settings:
Board: "Generic STM32F1 series"
Port: "/dev/tty/ACM0" (grayed out)
Debug symbols and core logs: "None"
Optimize: "Smallest (-Os default)"
Board part number: "BluePill F103C8"
C Runtime Library: "Newlib Nano (default)"
Upload method: "HID Bootloader 2.2"
USB support (if available): "CDC (generic 'Serial' supersede U(S)ART)"
U(S)ART support: "Enabled (generic 'Serial')"
USB speed (if available): "Low/Full Speed"
Breadboard connections:
STM32F103C8T6 PCF8574
GND --- GND
5V --- VCC
B6 --- SCL
B7 --- SDA
The only sketch to show any consistency is the I2CScanner:
Scanning...
I2C device found at address 0x27 !
done
Which is exactly what I'd expect.
All the libraries like LiquidCrystalI2C just won't work, so I tried Wire-only solution, just to look at error messages.
#include <Wire.h>
void WirebeginTransmission() {
Wire.beginTransmission(0x27);
}
const char* DecodeEndTransmission(unsigned errorCode) {
switch (errorCode) {
case 1: return "data too long to fit in transmit buffer";
case 2: return "received NACK on transmit of address";
case 3: return "received NACK on transmit of data";
case 4: return "other error";
case 5: return "timeout";
default: return (errorCode ? "UNKNOWN" : "ZERO");
}
}
void WireendTransmission(char* msg) {
unsigned code = Wire.endTransmission();
if (code > 0 && msg != NULL) {
Serial.printf("endTransmission: \"%s\" %s\n", msg, DecodeEndTransmission(code));
}
}
void setup() {
Serial.begin(9600);
while(!Serial);
Wire.begin();
Wire.setClock(400000);
WirebeginTransmission();
Wire.write(0x01); // Clear display
WireendTransmission("setup");
}
unsigned count = 0;
void loop() {
Serial.printf(">>%d<<\n", count++);
WirebeginTransmission();
Wire.write(0x80); // Set cursor to the first line
Wire.write("Hello, World!");
WireendTransmission("loop");
delay(1000);
}
I can only see endTransmission: "loop" other error; if I comment out all the Wire.write() inside loop(), I can see endTransmission: "loop" received NACK on transmit of address. Besides, the display doesn't get reliably cleared in spite of the alleged success.
It looks like power supply problem; I even plugged the programmed assembly into USB power supply 1500mA, but is won't show any difference. I tried different Wire.setClock() values, including the default. No difference.
What else can I check?