I have a problem in writing some Code. I'm definetly not a C++ expert - therefore it might be an easy problem for somebody who knows what he is doing.
I'm would like to use three Bluepill Boards communicating with a RaspberryPi over the I2C2 Bus as Slaves on the I2C2 Bus (the standard wire.begin() for the first BUS, I would like to use for some I2C Sensors) Every Bluepill Board collects Data and does some stuff which will be displayed on the Rpi.
I wrote some example code for the communication which works quite well. It is Basicly a combination of SCD30 Sensor and I2C examples. Not very Beautifull but it works.
Code: Select all
/*
Reading CO2, humidity and temperature from the SCD30
and send data to the Pi
Version 002: some safety stuff: flags for checkup i2c activity and reload the i2c Bus
VERSION 003: with watchdog
*/
#include <Wire.h>
#include <IWatchdog.h>
#include "SparkFun_SCD30_Arduino_Library.h" //Click here to get the library: http://librarymanager/All#SparkFun_SCD30
#define SLAVE_ADDRESS 0x09
#define DATA_TO_SEND_LENGHT 30
#define STM_I2C2_FREQ 100000
#define DONE 1
void getPINandVariableInitSettings(void);
void getWireSettings(void);
void getWire2Settings(void);
char number[30];
char test[DATA_TO_SEND_LENGHT];
char test2[DATA_TO_SEND_LENGHT];
int state = 0;
float f_CO2 = 0;
char c_CO2_buffer[8];
float f_humidity=0;
char c_humidity_buffer[8];
float f_temp=0;
char c_temp_buffer[8];
int I2CErrorCounter = 0;
int count2;
int F_firstTransmit = 0;
int F_transmit = 0;
// SDA SCL
TwoWire Wire2(PB11, PB10);
SCD30 airSensor;
void setup()
{
getPINandVariableInitSettings();
getWireSettings();
getWire2Settings();
if (IWatchdog.isReset(true)) {
digitalWrite(LED_BUILTIN,!digitalRead(LED_BUILTIN));
}
if (airSensor.begin() == false)
{
//Serial.println("Air sensor not detected. Please check wiring. Freezing...");
digitalWrite(LED_BUILTIN,!digitalRead(LED_BUILTIN));// Turn the LED from off to on, or on to off
delay (200);
digitalWrite(LED_BUILTIN,!digitalRead(LED_BUILTIN));// Turn the LED from off to on, or on to off
delay (200);
digitalWrite(LED_BUILTIN,!digitalRead(LED_BUILTIN));// Turn the LED from off to on, or on to off
delay (200);
digitalWrite(LED_BUILTIN,!digitalRead(LED_BUILTIN));// Turn the LED from off to on, or on to off
delay (200);
}
// Init the watchdog timer with 30 milliseconds timeout
IWatchdog.isReset();
IWatchdog.begin(50000);
if (!IWatchdog.isEnabled()) {
// LED blinks indefinitely
while (1) {
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
digitalWrite(LED_BUILTIN, LOW);
delay(100);
}
}
}
//********************************************************************************************************
//****************************************************LOOOP***********************************************
void loop()
{
// read out the Sensor values and store them in the Variable
if (airSensor.dataAvailable())
{
digitalWrite(LED_BUILTIN,!digitalRead(LED_BUILTIN));// Turn the LED from off to on, or on to off
f_CO2 = airSensor.getCO2();
dtostrf(f_CO2, 5, 0, c_CO2_buffer);
for (int i = 0; i<5;i++){
test[4+i] = c_CO2_buffer[i];
}
f_temp = airSensor.getTemperature();
dtostrf(f_temp, 5, 2, c_temp_buffer);
for (int i = 0; i<5;i++){
test[12+i] = c_temp_buffer[i];
}
f_humidity = airSensor.getHumidity();
dtostrf(f_humidity, 5, 2, c_humidity_buffer);
for (int i = 0; i<5;i++){
test[20+i] = c_humidity_buffer[i];
}
}
// if (test[8]==48){
// test[28]=41;
// }
if (test[5]==32){
I2CErrorCounter++;
if(I2CErrorCounter == 5){
getWireSettings();
I2CErrorCounter =0;
}
}
test[27]=I2CErrorCounter +48;
// read out PIN to Reset the I2C Bus
test[28]=digitalRead(PB3)+48;
if(digitalRead(PB3)==LOW){
getWireSettings();
getWire2Settings();
}
F_transmit = 0;
delay(15);
if(F_firstTransmit == 1 && F_transmit == 0){
getWire2Settings();
}
//delay(15);
delay(485);
}
//void(* resetFunc)(void)=0;
//********************GET get PIN and Variable Init Settings Routine**********************
// @brief: this functions sets the in and output Pins and initializes variables if needed;
void getPINandVariableInitSettings(void){
pinMode(LED_BUILTIN, OUTPUT);
// so und dann direkt auf GND legen.
pinMode(PB3, INPUT_PULLUP);
for (int i=0; i<DATA_TO_SEND_LENGHT ; i++){
test[i]=95;
}
for (int i=0; i<DATA_TO_SEND_LENGHT ; i++){
test2[i]=95;
}
test[0]='C';
test[1]='O';
test[2]='2';
test[3]=':';
test[10]='T';
test[11]=':';
test[18]='H';
test[19]=':';
}
//********************GET WIRE SETTINGS Routine**********************
void getWireSettings(void){
// initialize wire
Wire.begin();
}
// *******************************************
void getWire2Settings(void){
// initialize wire
Wire2.begin(SLAVE_ADDRESS);
//Wire2.setClock(STM_I2C2_FREQ);
Wire2.onReceive(receiveData2);
Wire2.onRequest(sendData2);
F_firstTransmit = 0;
}
// *****************************callback for received data***********************************
void receiveData2(int byteCount) {
//digitalWrite(LED_BUILTIN,!digitalRead(LED_BUILTIN));// Turn the LED from off to on, or on to off
int i = 0;
while (Wire2.available()) {
number[i] = Wire2.read();
i++;
}
number[i] = '\0';
//Serial.print(number);
} // end while
// *****************************callback for sending data*************************************
void sendData2() {
//digitalWrite(LED_BUILTIN,!digitalRead(LED_BUILTIN));// Turn the LED from off to on, or on to off
Wire2.write(test,sizeof(test));
F_firstTransmit = 1;
F_transmit = 1;
IWatchdog.reload();
}
//End of the program
Code: Select all
class MKE_data
{
private:
int BoardType;
char DataBuffer[MKE_DATA_BUFF_SIZE];
char DataConfig[MKE_DATA_BUFF_SIZE];
bool ConfigIsSent;
char I2C_BaseAdress;
char I2C_AdressOffset;
char I2C_Adress;
char AdressPIN[3];
TwoWire *Wire2;
public:
MKE_data(int type);
~MKE_data();
int getBoardType(void);
void val2buf(int value, int position);
void float2buf(float value, int position);
void printBuffer();
char getData (int position);
void setI2CAdrrOffset(void);
char getI2CAdrrOffset(void);
void updateI2CAdress(void);
char getI2CAdress(void);
void I2CSysBusInit();
void receiveSysBusData(int byteCount);
static void Wrapper2CallRecieveSysBusData(void* ptr2Object, int byteCount);
void sendSysBusData(void);
static void Wrapper2CallSendSysBusData(void* ptr2Object);
};
Code: Select all
Wire2 = new TwoWire(PB11, PB10)
I2CSysBusInit();
Code: Select all
void MKE_data::I2CSysBusInit(){
// initialize wire
Wire2->begin(getI2CAdress());
//Wire2.setClock(STM_I2C2_FREQ);
int byteCount;
Wire2->onReceive(Wrapper2CallRecieveSysBusData);
Wire2->onRequest(Wrapper2CallSendSysBusData);
//F_firstTransmit = 0;
}
Code: Select all
void MKE_data::Wrapper2CallSendSysBusData(void* ptr2Object)
{
// explicitly cast to a pointer to MKE_data
MKE_data* mySelf = (MKE_data*) ptr2Object;
// call member
mySelf->sendSysBusData();
}
void MKE_data::Wrapper2CallRecieveSysBusData(void* ptr2Object, int byteCount)
{
// explicitly cast to a pointer to MKE_data
MKE_data* mySelf = (MKE_data*) ptr2Object;
// call member
mySelf->receiveSysBusData(byteCount);
}
I would really appreciate some help!
Greetings, Jens