MQTT char array naar variabele conversie ?

Projecten die niet passen in bovenstaande onderwerpen
Berichten: 36
Geregistreerd: 16 Jun 2016, 21:23

MQTT char array naar variabele conversie ?

Berichtdoor john33 » 30 Jan 2023, 20:20

Beste forumleden,

via een Raspberry Pi, aangesloten op mijn slimme meter stuur ik dmv P1monitor de meterdata van het verbruik naar een MQTT broker.

Met een ESP8266 heb ik succesvol verbinding kunnen maken met de broker, en kan ik het verbruik uitlezen op een LCD display via i2c aangesloten op de ESP8266.

War gaat het mis?
De data die ik ontvang is met 3 cijfers achter de komma.
Bijvoorbeeld, op dit moment verbruik ik 0,187kW/h volgens het display.

Ik wil met deze waardes een boiler gaan aansturen, als ik de conversie goed heb verander ik het MQTT topic naar "teruglevering".
Maar wat mij tot nu toe nog niet lukt is om die waarde van 0,187 (char* omgezet naar string) om daar een variabele van te maken.
Getest met toInt, maar als resultaat krijg ik een 0, of een 1 bij een verbruik van +1000watt.

Hoe kan ik de string die ik heb omzetten naar een waarde van x,000 naar xxxx (1200 of zo iets) want daarmee kan ik wel sturen.

Code waar MQTT bericht mee ontvangen wordt:
Code: Alles selecteren
//MQTT data ontvangen en op LCD weergev
  Serial.print("Message arrived in topic: ");
  //Serial.println(topic);
  Serial.print("Message:");
  for (int i = 0; i < length; i++) {
  //Serial.print((char) payload[i]);

  //weergave op LCD scherm
  lcd.clear();
  payload[length] = '\0';
  String strPayload = String((char*)payload);
  int Val10 = Serial.read();                             //Val10 leest de serieele poort uit en slaat deze op als variabele
    if (isDigit(Val10)) {
      strPayload + - (char)Val10;

    }
    if (strPayload.toInt() <= 0, 000) {              //test stukje om cursor te laten knipperen bij aktieve boiler
      //Serial.println("BOILER");
      lcd.setCursor(15, 1);
      lcd.blink();
    }
    else
    {
      lcd.setCursor(15, 1);
      lcd.noBlink();
    }
    lcd.setCursor(0, 0);
    lcd.print("Consumption: ");
    lcd.setCursor(0, 1);
    lcd.print(strPayload);             //strPayload = de naar string geconverteerde char*
    lcd.print(" kW");
    Serial.println(strPayload);        //deze Serial.print geeft de juiste waarde weer

Advertisement

Berichten: 150
Geregistreerd: 26 Aug 2015, 11:57

Re: MQTT char array naar variabele conversie ?

Berichtdoor Frits1956 » 30 Jan 2023, 22:46

Een int kan alleen hele getallen bevatten. Probeer het eens met een float

Berichten: 29
Geregistreerd: 02 Nov 2022, 13:03

Re: MQTT char array naar variabele conversie ?

Berichtdoor ThHe » 31 Jan 2023, 01:44

Een oplossing bij 3 cijfers achter de ,

String s = "0,184";

Serial.begin(9600);
int v = 0;
for (int i = 0; i < s.length(); i++)
{
if (s.charAt(i) != ',') v = v *10 + (s.charAt(i) - '0');
}
Serial.println(v);
Serial.println(v / 1000., 3);

Berichten: 36
Geregistreerd: 16 Jun 2016, 21:23

Re: MQTT char array naar variabele conversie ?

Berichtdoor john33 » 01 Feb 2023, 20:26

Omzetten naar float, dat was de truuk .
Daarna een variabele aangemaakt die de float x 1000 vermenigvuldigd en het werkt.

Hiermee kan ik verder.
Bedankt.

Berichten: 36
Geregistreerd: 16 Jun 2016, 21:23

Re: MQTT char array naar variabele conversie ?

Berichtdoor john33 » 05 Feb 2023, 22:29

Nu toch weer iets raars waar ik niet uit kom,

Mijn sketch loopt tot en met de weergave op het lcd scerm prima.
Maar zodra ik extra functionaliteit toevoeg, iets aansturen op basis van de waarde op het lcd scherm dan blijft de eerste ontvangen waarde op het scherm staan en wordt niet meer ververst.
dit is de sketch die werkt:
Code: Alles selecteren
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

//Global variables
LiquidCrystal_I2C lcd(0x27, 16, 2);    // set the LCD address to 0x27 for a 16 chars and 2 line display
int temppin = A0;                      //TMP36 temperatuur sensor op A0
//int buttonPin = 4;
int PWM_Output = 2;                    //=D4 pwm output naar KEMO kastje
//int minimumWatts = 250;                //minimaal verbruik huis
int val = 0;                           //variabele om watts op te slaan
int val1 = 0;                          //variabele om vermogen naar boiler op te slaan
int val2 = 0;                          //variabele om ontvangen gegevens op te slaan
int val3 = 0;
//const int LED = 6;                     //Led knippert sneller naar gelang er meer power naar de boiler gaat
int Relais = 4;                        //D2 Relais om 230 volt echt af te sluiten als het zonvermogen te laag is of boiler op temperatuur
//int BoilerLed = 8;                     // led om status van boiler aan te geven
int i = 0;

//drukknop
int buttonPushCounter = 0;
int buttonState = 0;
int lastButtonState = 0;
unsigned long previousMillis = 0;      // slaat de tijd op
const long interval = 500;             // interval tussen meetmomenten
   

// WiFi
const char *ssid = "*********"; // Enter your WiFi name
const char *password = "********";  // Enter WiFi password

// MQTT Broker
const char *mqtt_broker = "broker.******.com";
const char *topic = "p1monitor/smartmeter/consumption_kw";
const int mqtt_port = 1883;

WiFiClient espClient;
PubSubClient client(espClient);

//end of global variables

void setup() {
  // Set software serial baud to 115200;
  Serial.begin(115200);
  lcd.init();
  lcd.backlight();
 
  //pinMode(buttonPin, INPUT);
  //pinMode(LED, OUTPUT);
  pinMode (2, OUTPUT);                  //uitgang naar KEMO kastje
  //pinMode (6, OUTPUT);                  //uitgang voor LED
  pinMode (4, OUTPUT);                  //uitgang voor Relais
  //pinMode (8, OUTPUT);                  //uitgang voor boilerled status
  lcd.setCursor(1, 0);
  lcd.print("Solar Diverter");
  lcd.setCursor(3, 1);
  lcd.print("by JG TECH");
  delay(5000);
  lcd.clear();
  //lcd.print("druk op knop");

 // End of setup
 
  // connecting to a WiFi network
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      lcd.setCursor(0, 0);
      lcd.print("connecting...");
      Serial.println("Connecting to WiFi..");
  }
  Serial.println("Connected to the WiFi network");
  //connecting to a mqtt broker
  client.setServer(mqtt_broker, mqtt_port);
  client.setCallback(callback);
  while (!client.connected()) {
      String client_id = "esp8266-client-";
      client_id += String(WiFi.macAddress());
      Serial.printf("The client %s connects to the public mqtt broker\n", client_id.c_str());
      if (client.connect(client_id.c_str())) {
          Serial.println("Public ****** mqtt broker connected");
      } else {
          Serial.print("failed with state ");
          Serial.print(client.state());
          delay(2000);
      }
  }
  // publish and subscribe
  client.publish(topic, "p1monitor/smartmeter/consumption_kw");
  client.subscribe(topic);
}

//In deze loop moet alles plaatsvinden:
 
void callback(char *topic, byte *payload, unsigned int length) {            //unsigned int kan geen negatieve getallen opslaan
  //temperatuurmeter van boiler uitlezen
  int reading = analogRead(temppin);
  float voltage = reading * (1100 / 1024.0); //converteer de uitlezing in voltage
  // Converteer het voltage in temperatuur in Celsius:
  float temperature = voltage / 12;
  // Print de temperatuur in de Serial Monitor:
  //Serial.println("boilertemp");
  Serial.println(temperature);
 
  //MQTT data ontvangen en op LCD weergeven
   
  Serial.print("Message arrived in topic: ");
  //Serial.println(topic);
  //Serial.print("Message:");
  for (int i = 0; i < length; i++) {
  //Serial.print((char) payload[i]);
     
  //weergave op LCD scherm
      lcd.clear();
      payload[length] = '\0';
      String strPayload = String((char*)payload);
      int Val10 = Serial.read();                     //Val10 wat doet die?
      if (isDigit(Val10)){
        strPayload +- (char)Val10;
      }
      lcd.setCursor(0, 0);
      lcd.print("Consumption: ");
      lcd.setCursor(0, 1);
      lcd.print(strPayload);             //strPayload = de naar string geconverteerde char*
      //lcd.print(val3);                   //testje
      lcd.print(" kW");
      //Serial.println(strPayload);     //deze Serial.print geeft de juiste waarde weer
      //--------------------------------------------------------------------------------------------
      // Boiler aansturen
    float num = strPayload.toFloat();            //converteer de payload naar een float met de naam num
    Serial.println(num);
    val3 = (num *1000);                          //variabele val3 is float num x 1000, om hele watt`s te krijgen
    Serial.println (val3);                           //print de waarde val3 in de serieele monitor
    //if (val3 > 1){
    //digitalWrite(Relais, HIGH);                  //Schakel 230 volt in naar KEMO kastje
    //digitalWrite(BoilerLed, HIGH);               //laat de LED voor boiler status branden
    //val2 = (val3 / 8,62);                        //val2 is maximaal 2000(watt output) 2000/8.62 = 255, max uitstuurwaarde
    //analogWrite(PWM_Output, val2);                        //stuur pin 5 met PWM uit
    //Serial.println(val2);                        //laat de uitstuurwaarde zien in de serieele monitor
    //}
    //-------------------------------------------------------------------------------------------------
    //boiler aansturing met voorwaardes
   
    //if (val3 < 1){                              //als er geen terug lvering is
    //digitalWrite(Relais, LOW);                  //Schakel 230 volt uit naar KEMO kastje
    //digitalWrite(BoilerLed, LOW);               //laat de LED voor boiler status uit
    //}
    //voorwaarde scheppen om boiler af te schakelen bij bereiken max temperatuur
    //if (temperature >= 50) {                     //als de boilertemperatuur groter of gelijk dan 50 graden is
    //analogWrite(PWM_Output, 0);                         //pin 5 mag niets meer uitsturen
    //Serial.println("boiler uit");
    //digitalWrite(Relais, LOW);                 //Schakel 230 volt uit naar KEMO kastje
    //digitalWrite(BoilerLed, LOW);              //laat de LED voor boiler status uit
    //}
    //else
    //{
    //analogWrite(PWM_Output, val3);                      //in andere gevallen wel
   
   // }
 
      }
 
  Serial.println();
  Serial.println("-----------------------");
}

void loop() {
  client.loop();

}


Als is ik vanaf //if (val3 > 1){ de // weg haal of die functies aan te zetten dan wordt het display niet meer geupdate, de eerst ontvangen waarde blijft in het scherm staan.
In de serieele monitor zie ik wel keurig de nieuwe waardes binnen komen, dat dan weer wel.
Waar ga ik verkeerd ? ik heb de lcd code al op verschillende plaatsen neergezet zonder resultaat.

Berichten: 150
Geregistreerd: 26 Aug 2015, 11:57

Re: MQTT char array naar variabele conversie ?

Berichtdoor Frits1956 » 06 Feb 2023, 01:25

Voor zover ik kan zien is er geen functie client.loop() die in de main wordt aangeroepen.
Bedoel je niet callback() ???

Berichten: 36
Geregistreerd: 16 Jun 2016, 21:23

Re: MQTT char array naar variabele conversie ?

Berichtdoor john33 » 12 Feb 2023, 11:36

De code zoals afgebeeld werkt.
Echter stom stom stom, nog maar eens naar de hardware gekeken.....

Ik moet nog wennen aan dat ik met een ESP8266 werk, de pin namen zijn net even anders als bij een Arduino.
En daar ging het mis, het "relais" had ik op pin 4 staan, maar daar zit de SDA al op van het I2C deel voor het display.
Nooit aangedacht.

Ik heb wel een stukje code herschreven, maar nu werkt het zoals ik het wil.
Ik heb een extra void aangemaakt, void boilercontrol en in de main loop alle sturing laten plaatsvinden in plaats van het Callback gedeelte.

Terug naar Overige projecten

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 5 gasten