AndreK
November 28, 2024, 6:35pm
1
What you see here is an attempt to debug much bigger program:
I recently moved it to STM32, and ran into this trouble:
In short: the program never sees any packet adressed to it (address 0xB or 11)
I DO see and decode packets incoming on the I2C bus, with a scope connected to SCL1/PB6/22 and SDA1/PB7/23 .
I do NOT get to see them in the serial monitor.
#include <Wire.h>
long lastms;
void receiveEvent(int howMany) {
int x = Wire.read();
Serial.print("U:0x");
Serial.println(x, HEX);
}
void requestEvent() {
Serial.println("req");
}
void setup() {
Serial.begin(115200);
pinMode(22,INPUT);
pinMode(23,INPUT);
Wire.setSCL(22);
Wire.setSDA(23);
Wire.begin(11); // join i2c bus as slave
Wire.onRequest(requestEvent); // register event
Wire.onReceive(receiveEvent); // register event
lastms = millis();
}
void loop() {
if (millis() > lastms+1000) {
Serial.print("=");
lastms = millis();
}
}
First thought: if receiveEvent
and requestEvent
are called from an interrupt, does Serial I/O work in an interrupt on the STM32F103?
AndreK
November 28, 2024, 6:42pm
3
just to make sure, I did:
#include <Wire.h>
long lastms;
int x = 0;
void receiveEvent(int howMany) {
x = Wire.read();
}
void requestEvent() {
Serial.println("req");
}
void setup() {
Serial.begin(115200);
pinMode(22, INPUT);
pinMode(23, INPUT);
Wire.setSCL(22);
Wire.setSDA(23);
Wire.begin(11); // join i2c bus as slave
Wire.onRequest(requestEvent); // register event
Wire.onReceive(receiveEvent); // register event
lastms = millis();
}
void loop() {
if (millis() > lastms + 1000) {
Serial.print("=");
lastms = millis();
}
if (x != 0) {
Serial.print("U:0x");
Serial.println(x, HEX);
x = 0;
}
}
It did not help , I still only get "="
Also: please have in mind that the scope is connected to said pins, so the pullups/connection is ok.
If requestEvent
and receiveEvent
are called from an interrupt context, x
should be declared volatile
otherwise the compiler might optimize away checking it in loop
. And the code is still printing from requestEvent
.
AndreK
November 28, 2024, 7:17pm
5
I tried this, it did not help,
#include <Wire.h>
long lastms;
volatile int x = 0;
volatile int y = 0;
void receiveEvent(int howMany) {
x = Wire.read();
}
void requestEvent() {
y = 1;
}
void setup() {
Serial.begin(115200);
pinMode(22, INPUT);
pinMode(23, INPUT);
Wire.setSCL(22);
Wire.setSDA(23);
Wire.begin(11); // join i2c bus as slave
Wire.onRequest(requestEvent); // register event
Wire.onReceive(receiveEvent); // register event
lastms = millis();
}
void loop() {
if (millis() > lastms + 1000) {
Serial.print("=");
lastms = millis();
}
if (x != 0) {
Serial.print("U:0x");
Serial.println(x, HEX);
x = 0;
}
if (y != 0) {
Serial.println("V");
y = 0;
}
}
This worked fine for me on my admittedly ancient STM32 core that I haven't updated since forever. I rigged up a Pico to send a message over I2C once every 2 seconds and the Blue Pill displays them.
#include <Wire_slave.h>
volatile char buf[80];
volatile unsigned count = 0;
volatile bool received = false;
void setup() {
Serial.begin(115200);
delay(5000);
Serial.println("Started");
Wire.begin(11);
Wire.onReceive(receiveEvent);
}
void loop() {
if( received ) {
for( unsigned i=0; i<count; ++i ) {
Serial.print(buf[i]);
}
received = false;
count = 0;
}
delay(50);
}
void receiveEvent(int howMany) {
for( int i=0; i<howMany; ++i ) {
char c = Wire.read();
if( count < sizeof buf ) {
buf[count++] = c;
}
}
received = true;
}
Remember, it's an ancient core that I'm using. It may no longer be that way.
system
Closed
May 27, 2025, 8:12pm
9
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.