Ben bezig om een uitgebreide besturing voor de moestuin kas te maken in combinatie met een uitgebreid weerstation.
besturing in de kas is een uno maar de verwerking van het weerstation en afbeelden op een lcd is een mega. basis code voor de uno heb ik werkend. dit geeft 5 variabele. 2 keer temperatuur, 2 keer luchtvochtigheid en de stand van het dakraam.
deze variabele wil ik dus via serieel naar de mega sturen zodat ik ze daar weer kan verwerken. maar ik kan nergens voorbeeld, uitgebreide uitleg of tutorials vinden hier voor. wie kan me helpen?
De eerste vraag is waarom je denkt een Uno en een Mega nodig te hebben? Kun je het niet allemaal met slechts een Mega doen?
De Uno heeft slechts één seriële poort. Je zult eerst moeten besluiten of je die wilt gebruiken of niet. Als je die wilt gebruiken zul je voordat je een upload doet naar de Uno de verbinding met de Mega los moeten nemen. Het alternatief is gebruik te maken van SoftwareSerial of AltSoftSerial; de grootste beperking is de beperkte baudrate (19200 schient OK te zijn).
De Mega heeft 4 UARTs (seriële poorten); maak gebruik van Serial1/2/3, niet van Serial die gebruikt wordt voor communicatie met de PC.
Ik weet niet hoe goed je Engels is maar je kunt het geheel baseren op Robin's Serial Input Basics - updated; voorbeeld 5 is in het algemeen het meest geschikt.
Het artikel beschrijft de ontvanger kant van het geheel, je moet zelf de zender schrijven die het juiste formaat stuurt.
Dan zoek je niet goed
dit ga ik dalijk eens bekijken.
En ja de uno zit in de kas aangezien die niet alleen meet maar ook van alles aanstuurt daar. de mega dalijk binnen om uit eindelijk ook daar nog een en ander aan te sturen.
en kan best wel wat vinden over serial communicatie maar dat is dan beperkt tot het sturen van vaste waardes of bv een tekst die dan word doorgestuurd naar bv een display. niet echt hoe ik diverse variabelen van de een naar de ander kan krijgen dat ik in de ontvanger ook nog weet wat welke is om daar verder te kunnen verwerken.
en helaas voor mij is het belangrijk dat ik om dit goed te begrijpen en kunnen leren het moet zien in een voorbeeld. heb wel ergens iets voorbij zien komen wat een bepaalde string maakt en die weer afbreekt bij ontvangst. op die manier zou je dus moeten kunnen zien welke variabele welke waarde verstuurt heef. maar dat is dus alleen een stukje uitleg zonder voorbeeld en dan begrijp ik dat weer niet helemaal helaas.
Aan de Uno kant kun je dit als leidraad gebruiken; je kunt het allemaal testen met een terminal programna (bv seriële monitor).
Serial.print("<");
Serial.print(value1);
Serial.print(",");
Serial.print(value2);
Serial.print(",");
Serial.print(value3);
Serial.print(">");
Zodra dat allemaal werkt kun je bv. de Mega's Serial1 aansluiten op de Uno ( Rx naar Tx1, Tx naar Rx1).
En dan kun aan de Mega kant Robin's voorbeeld 5 pakken; je moet Robin's programma zo aanpassen dat het Serial gebruikt voor communicatie met de PC en Serial1 voor communicatie met de Uno.
Als je je Uno programma hier neerzet (vergeet niet om code tags te gebruiken) kunnen we uitvogelen over wat voor soort data we praten (floats, ints, text, ...).
Ik gebruik nu een mobiel dus kan even niet verder helpen.
Ik veronderstel dat er toch wat afstand is tussen het display/processor binnen en dat in je serre/moestuinkast. RS232 of gewone UART op 5V is daar zeker niet voor geschikt. Je zal dan eerder RS485/modbus moeten gebruiken. Deze is in tegenstelling tot RS232 half duplex. Je zal dus 1 master hebben en 1 slave. Of je moet RS422 uitvoeren. Dat is een dubbele RS485. Niet vergeten de beide einden af te sluiten met 120Ω.
Persoonlijk zou ik eerder een WiFi connectie nemen en data doorsturen via MQTT en JSON. Dan heb je wel bidirectionele communicatie en je hoeft geen draden te trekken. Alleen een MQTT server extern instellen of op je eigen NAS.
Ter aanvulling.
-RS232 met RS232 signaalniveaus tussen +5 en +15V voor een 0 en -5V en -15V voor een 1 wordt 15m als maximum aanzien voor 9600Bd. 30m bij 4800Bd. Maar een arduino of ESP heeft geen negatieve spanning aan boord. Een ESP haalt amper TTL niveau met zijn 3,3V.
-RS485 heeft een maximum lengte van 1200m en heeft dan een maximale snelheid van 100kbs. Op 12m 35Mbps. Voorwaarde wel een getwiste kabel (liefst impedantie 120Ω en aan beide zijden correct afgesloten met 120Ω).Gewoon UTP kan ook gebruikt worden maar is net buiten specs. Voldoende voor niet de maximale lengte en niet de maximale snelheid.
kom er nog niet uit. heb inmiddels ook zoveel zitten lezen dat ik even niet meer weet wat ik nu moet aanhouden. communicatie tussen de 2 lukt wel. het lukte op een gegeven moment ook om duidelijk een float goed door te krijgen (zoveel ge probeert dat dat nu ook niet meer lukt). maar kom er vooral niet uit hoe ik of 5 floats apart door stuur en dan nog weet welke wat is. of waar ik nu laaste uren na heb zitten kijken ze samenvoegen versturen en weer scheiden. dan heb je zeker de juiste waarde bij de juiste float. er zijn vele voorbeelden. maar een voorbeeld van zender en onvanger die meerdere floats verstuurt en ook apart opslaat kan ik nog steeds niet vinden voor serial com.
kan iemand mij daar aan helpen?
dan kan ik ook beter begrijpen wat ik aan het doen ben.
leren uit alleen theorie is erg moeilijk voor me als ik iets heb om vanuit te gaan kan ik het veel beter begrijpen wat ik aan het doen ben en hoe het werkt.
<//Libraries
#include <DHT.h>;
//int LDRInput=A0; //Set Analog Input A0 for LDR.
//pinMode (LDRInput,INPUT);
//Constants
const int raamopen_pin = 7;
const int raamdicht_pin = 8;
const int ventilator_pin = 9;
//pinMode(10, OUTPUT);
//inMode(11, OUTPUT);
#define DHTbuitenPIN 2 // what pin we're connected to
#define DHTbuitenTYPE DHT22 // DHT 22 (AM2302)
DHT dhtbuiten(DHTbuitenPIN, DHTbuitenTYPE); //// Initialize DHT sensor for normal 16mhz Arduino
#define DHTkasPIN 3 // what pin we're connected to
#define DHTkasTYPE DHT22 // DHT 22 (AM2302)
DHT dhtkas(DHTkasPIN, DHTkasTYPE); //// Initialize DHT sensor for normal 16mhz Arduino
int LDRInput=A0; //Set Analog Input A0 for LDR.
unsigned long tempMillis;
unsigned long dnMillis;
// funties
void temperaturen();
void display(String currState);
void dagnacht();
void raamstate(String currState);
void serial(); //com
//Variables
int chk;
float humbuiten; //Stores humidity value
float tempbuiten; //Stores temperature value
float humkas; //Stores humidity value
float tempkas; //Stores temperature value
float dn;
float rs;
float tempC = 0; //com
char text[20] ; //com
char charVal[6]; //com
void setup()
{
pinMode(LDRInput,INPUT);
pinMode(raamopen_pin, OUTPUT);
pinMode(raamdicht_pin, OUTPUT);
pinMode(ventilator_pin, OUTPUT);
//pinMode(10, OUTPUT);
//pinMode(11, OUTPUT);
Serial.begin(9600);
dhtbuiten.begin();
dhtkas.begin();
//tempMillis = millis();
//dnMillis = millis();
}
void loop()
{
temperaturen();
dagnacht();
serial();
raamstate();
}
void temperaturen()
{
static unsigned long tempMillis = millis();
if (millis() - tempMillis > 5000)
{//Read data and store it to variables hum and temp
humbuiten = dhtbuiten.readHumidity();
tempbuiten= dhtbuiten.readTemperature();
//Print buiten temp and humidity values to serial monitor
Serial.print("Humidity buiten: ");
Serial.print(humbuiten);
Serial.print(" %, Temp buiten: ");
Serial.print(tempbuiten);
Serial.println(" Celsius");
humkas = dhtkas.readHumidity();
tempkas= dhtkas.readTemperature();
//Print kas temp and humidity values to serial monitor
Serial.print("Humidity kas: ");
Serial.print(humkas);
Serial.print(" %, Temp kas: ");
Serial.print(tempkas);
Serial.println(" Celsius");
tempMillis = millis();
}
//else
//{
// loop();
//}
}
void dagnacht()
{
static unsigned long dnMillis = millis();
if (millis() - dnMillis > 50000)
{
int value=analogRead(LDRInput);//Reads the Value of LDR(light).
Serial.println("LDR value is :");//Prints the value of LDR to Serial Monitor.
Serial.println(value);
if(value<300)
{
dn = 1;
Serial.println(dn);//The LED turns ON in Dark.
Serial.println("nacht");
}
else
{
dn = 2;
Serial.println(dn);
Serial.println("dag");//The LED turns OFF in Light.
}
dnMillis = millis();
}
//else
//{
//loop();
//}
}
void raamstate()
{
static unsigned long raamMillis = millis();
static uint16_t raamdelay;
enum class raamstate : uint8_t
{
open, //default 0
dicht, // default 1
ventilatie, // default 2
warmenacht, // default 3 }
};
static raamstate currState = raamstate::dicht;
switch (currState) {
case raamstate::dicht:
//Serial.println ("raam dicht");
if (millis() - raamMillis > 5000 && tempkas > 25 && dn == 2 && rs != 1)
{
rs = 1;
Serial.println("Raam gaat open");
digitalWrite(7, HIGH);
Serial.println("ventilator aan");
digitalWrite(9, HIGH);
delay (5000);
digitalWrite(7, LOW);
Serial.println("Raam open");
currState = raamstate::open;
raamMillis = millis();
}
else if (millis() - raamMillis > 5000 && humkas > 50 && dn == 2 && rs != 1)
{
rs = 1;
Serial.println("raam gaat naar ventilatie");
digitalWrite(7, HIGH);
Serial.println("ventilator aan");
digitalWrite(9, HIGH);
delay (2000);
digitalWrite(7, LOW);
Serial.println("Raam op ventilatie");
currState = raamstate::ventilatie;
raamMillis = millis();
}
else if (millis() - raamMillis > 5000 && humkas > 50 && tempbuiten > 25 && dn == 1 && rs != 1)
{
rs = 1;
Serial.println("raam gaat naar ventilatie");
digitalWrite(7, HIGH);
delay (2000);
digitalWrite(7, LOW);
Serial.println("Raam op ventilatie");
currState = raamstate::ventilatie;
raamMillis = millis();
}
else if (millis() - raamMillis > 5000 && tempkas > 25 && tempbuiten > 25 && dn == 1 && rs != 1)
{
rs = 1;
Serial.println("raam gaat open");
digitalWrite(7, HIGH);
delay (5000);
digitalWrite(7, LOW);
Serial.println("Raam open");
currState = raamstate::open;
raamMillis = millis();
}
break;
case raamstate::open:
//Serial.println ("raam open");
if (millis() - raamMillis > 5000 && tempkas < 25 && rs != 2)
{
rs = 2;
Serial.println("raam gaat dicht");
digitalWrite(8, HIGH);
Serial.println("ventilator uit");
digitalWrite(9, LOW);
delay (5000);
digitalWrite(8, LOW);
Serial.println("Raam dicht");
raamMillis = millis();
currState = raamstate::dicht;
}
else
{
if (millis() - raamMillis >5000 && dn == 1 && rs != 2 && tempbuiten < 25)
{
rs = 2;
Serial.println("raam gaat dicht ivm nacht");
digitalWrite(8, HIGH);
Serial.println("ventilator uit");
digitalWrite(9, LOW);
delay (5000);
digitalWrite(8, LOW);
Serial.println("Raam dicht");
raamMillis = millis();
currState = raamstate::dicht;
}
}
break;
case raamstate::ventilatie:
//Serial.println("ventilatie");
if (millis() - raamMillis > 5000 && humkas < 50 and tempkas < 25 && rs != 3)
{
rs = 3;
Serial.println("raam van ventilatie naar dicht");
digitalWrite(8, HIGH);
Serial.println("ventilator uit");
digitalWrite(9, LOW);
delay (2000);
digitalWrite(8, LOW);
Serial.println("Raam dicht");
currState = raamstate::dicht;
raamMillis = millis();
}
else if (millis() - raamMillis > 5000 && humkas >50 and tempkas > 25 && dn == 2 && rs != 3)
{Serial.println("raam van ventilatie naar open");
digitalWrite(7, HIGH);
Serial.println("ventilator aan");
digitalWrite(9, HIGH);
delay (3000);
digitalWrite(3, LOW);
Serial.println("Raam open");
currState = raamstate::open;
raamMillis = millis();
}
else if (millis() - raamMillis >5000 && dn == 1 && rs != 3 && tempbuiten < 25)
{
rs = 3;
Serial.println("raam gaat dicht ivm nacht");
digitalWrite(8, HIGH);
Serial.println("ventilator uit");
digitalWrite(9, LOW);
delay (5000);
digitalWrite(8, LOW);
Serial.println("Raam dicht");
raamMillis = millis();
currState = raamstate::dicht;
}
break;
}
}
void serial()
{
strcat(text, "Temp is: "); //append to empty string
tempC = (tempkas) ;
//this is a float we want it as a c-string:
dtostrf(tempC, 5, 1, text);
//dtostrf(tempkas, 5, 1, charVal);
//5 is min width, 1 is precision; float value is copied to charVal
strcat(text, charVal); //append the value
text[16] = 0; //terminate the cstring
strcat(text, "C"); //append a C
Serial.println(text); //print to local screen for debug
}
>
reciever:
<#include <DHT.h>
//#include <DHT_U.h>
#define DHT1PIN 2
#define DHT1TYPE DHT22
DHT DHT1(DHT1PIN, DHT1TYPE);
//Transmitter Code
#include <SoftwareSerial.h>
// Serial link(0, 1); // Rx, Tx
byte lm35Pin = A0;
float lm35V = 0;
float tempC = 0;
byte greenLED = 12;
char text[20] ;
char charVal[6];
void setup()
{
// link.begin(9600);
Serial.begin(9600);
pinMode(greenLED, OUTPUT);
DHT1.begin();
}
void loop()
{
strcat(text, " Temp 1: "); //append to empty string
//digitalWrite(greenLED, HIGH);
delay(10);
//digitalWrite(greenLED, LOW);
//lm35V = analogRead(lm35Pin);
lm35V = DHT1.readTemperature();
tempC = (lm35V/500) * 500;
//this is a float we want it as a c-string:
dtostrf(tempC, 2, 1, charVal);
//5 is min width, 1 is precision; float value is copied to charVal
strcat(text, charVal); //append the value
text[16] = 0; //terminate the cstring
//strcat(text, " C"); //append a C
Serial.println(text); //print to local screen for debug
//link.println(text);
delay(200);
}
>
Separate the data by commas. And you don't have to build a text first. Print a value, print a comma, print another value, print a comma etc. Look at the example I gave earlier.
maar hoe krijg ik ze dan bij ontvangst weer in de juiste float opgeslagen?
op die manier versturen lukt wel. maar kwam er totaal niet uit hoe ik ze dan weer op een goede manier kan verwerken.
In post #2 staat een link. Voir floats kun je atof() gebruiken inplaats van atoi().
Je weet in welke volgorde je gegevens verstuurd en ze zulken ook in die volgorde aankomen
ga ik mee aan de gang
heb nu dit maar krijg alleen maar vierkantjes door nu.
<#include <DHT.h>
//#include <DHT_U.h>
#define DHT1PIN 2
#define DHT1TYPE DHT22
DHT DHT1(DHT1PIN, DHT1TYPE);
//Transmitter Code
#include <SoftwareSerial.h>
byte lm35Pin = A0;
float lm35V = 25.0;
float tempC = 30.0;
float buiten = 20.5;
float binnen = 13.8;
byte greenLED = 12;
char text[20] ;
char charVal[6];
void setup()
{
Serial.begin(9600);
pinMode(greenLED, OUTPUT);
DHT1.begin();
}
void loop()
{
delay (2000);
Serial.print("<");
Serial.print(lm35V);
Serial.print(",");
Serial.print(buiten);
Serial.print(",");
Serial.print(binnen);
Serial.print(",");
Serial.print(tempC);
Serial.print(">");
delay(200);
}
>
en dit bij de mega:
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use when parsing
// variables to hold the parsed data
//char messageFromPC[numChars] = {0};
//int integerFromPC = 0;
//
float lm35V = 00.0;
float tempC = 00.0;
float buiten = 00.0;
float binnen = 00.0;
boolean newData = false;
//============
//Receiver code
// #include <SoftwareSerial.h>
// SoftwareSerial link(2, 3); // Rx, Tx
//#include <Serial1.h>
byte greenLED = 12;
char cString[20];
byte chPos = 0;
byte ch = 0;
char dataStr[6];
void setup()
{
Serial.begin(9600); //setup software serial
Serial1.begin(9600); //setup serial monitor
pinMode(greenLED, OUTPUT);
Serial.begin(9600);
Serial.println("This demo expects 3 pieces of data - text, an integer and a floating point value");
Serial.println("Enter data in this style <HelloWorld, 12, 24.7> ");
Serial.println();
}
//============
void loop() {
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with \0
parseData();
showParsedData();
newData = false;
}
}
//============
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial1.available() > 0 ){//&& newData == false) {
rc = Serial1.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
//============
void parseData() { // split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
// strtokIndx = strtok(tempChars,","); // get the first part - the string
// strcpy(lm35V, strtokIndx); // copy it to messageFromPC
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
lm35V = atof(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
tempC = atof(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ",");
buiten = atof(strtokIndx); // convert this part to a float
strtokIndx = strtok(NULL, ",");
binnen = atof(strtokIndx); // convert this part to a floa
}
//============
void showParsedData() {
Serial.print("lm35V ");
Serial.println(lm35V);
Serial.print("tempC ");
Serial.println(tempC);
Serial.print("buiten ");
Serial.println(buiten);
Serial.print("binnen ");
Serial.println(binnen);
// if (link.available())
// Serial.write(link.read());
// if (Serial.available())
// link.write(Serial.read());
// while(Serial1.available())
// {
//read incoming char by char:
//ch = Serial1.read();
//cString[chPos] = ch;
//chPos++;
//digitalWrite(greenLED, HIGH); //flash led to show data is arriving
//delay(10);
//digitalWrite(greenLED, LOW);
//}
//cString[chPos] = 0; //terminate cString
//chPos = 0;
Serial.print(cString);
}>
Controleer of de baudrate van de Mega (Serial1.begin()) overeenkomt met de baudrate van de seriële monitor.
Ik snap niet waarom je recvWithStartEndMarkers() aangepast hebt; het enige dat je zou moeten aanpassen is parseData(); en je hebt daar in ieder geval een foutje in,
De eerste keer dat je strtok() aanroept moet je de pointer naar de text mee geven, niet NULL.
Dit is een aangepaste versie voor de Mega. Om het eenvoudiger te maken om aan te passen welke seriële poort op de Mega gebruikt wordt hev ik een #define toegevoegd.
#define UNOSERIAL Serial1
Als je eerst wilt testen met de seriële monitor kun je Serial1 veranderen naar Serial.
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use when parsing
#define UNOSERIAL Serial1
// variables to hold the parsed data
//char messageFromPC[numChars] = {0};
//int integerFromPC = 0;
//
float lm35V = 00.0;
float tempC = 00.0;
float buiten = 00.0;
float binnen = 00.0;
boolean newData = false;
//============
//Receiver code
// #include <SoftwareSerial.h>
// SoftwareSerial link(2, 3); // Rx, Tx
//#include <Serial1.h>
byte greenLED = 12;
char cString[20];
byte chPos = 0;
byte ch = 0;
char dataStr[6];
void setup()
{
Serial.begin(9600); //setup software serial
UNOSERIAL.begin(9600);
pinMode(greenLED, OUTPUT);
Serial.println("This demo expects 3 pieces of data - text, an integer and a floating point value");
Serial.println("Enter data in this style <HelloWorld, 12, 24.7> ");
Serial.println();
}
//============
void loop()
{
recvWithStartEndMarkers();
if (newData == true)
{
strcpy(tempChars, receivedChars);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with \0
parseData();
showParsedData();
newData = false;
}
}
//============
void recvWithStartEndMarkers()
{
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (UNOSERIAL.available() > 0 && newData == false)
{
rc = UNOSERIAL.read();
if (recvInProgress == true)
{
if (rc != endMarker)
{
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars)
{
ndx = numChars - 1;
}
}
else
{
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker)
{
recvInProgress = true;
}
}
}
//============
void parseData()
{
Serial.print(F("Received: "));
Serial.println(tempChars);
// split the data into its parts
char* strtokIndx; // this is used by strtok() as an index
// strtokIndx = strtok(tempChars,","); // get the first part - the string
// strcpy(lm35V, strtokIndx); // copy it to messageFromPC
strtokIndx = strtok(tempChars, ","); // this continues where the previous call left off
lm35V = atof(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
tempC = atof(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ",");
buiten = atof(strtokIndx); // convert this part to a float
strtokIndx = strtok(NULL, ",");
binnen = atof(strtokIndx); // convert this part to a floa
}
//============
void showParsedData()
{
Serial.print("lm35V ");
Serial.println(lm35V);
Serial.print("tempC ");
Serial.println(tempC);
Serial.print("buiten ");
Serial.println(buiten);
Serial.print("binnen ");
Serial.println(binnen);
}
Getest met een Mega (Serial2) en Leonardo (ipv Uno).
Opmerkingen:
- Je stuurt tekst, je ontvangt tekst en je stuurt daarna weer tekst; de omzetting naar een int of float is niet noodzakelijk in dit scenario. Maar later misschien wel.
- Robin gebruikt tempChars voor het splitsen en analyseren van de ontvangen tekst. Dit is niet strikt noodzakelijk als je er geen donder om geeft dat de tekst na het splitsen niet meer hetzelfde is.
dit moet ik dus veranderen in:
< strtokIndx = strtok(tempC, ","); // this continues where the previous call left off
tempC = atof(strtokIndx); // convert this part to an integer>
en moet ik dan nog bij de volgende ook NULL weghalen en na de komma pas de verwijzing?
Nee; kijk naar het programma in post #12.
yes eindelijk heb ik het voor elkaar.
echt heel erg bedankt voor je hulp en geduld
alleen heel raar. als ik die float zelf een waarde geef bv 33.25. perfect stuurt hij door en ontvangt hij ook goed. maar als ik de float verstuur na dat ik hem van de sensor lees krijg ik nan op de ontvanger.
<humkas = (34.20);
tempkas = (18.90);
humbuiten = dhtbuiten.readHumidity();
tempbuiten = dhtbuiten.readTemperature();
>
maar hij laat op de zender wel zien op de serialmonitor dat hij ze goed verzend.
waar kan dat dan aan liggen?
Heb je tussen de Mega en de Uno een grond verbinding? Dat kan via USB zijn als beiden aangesloten zijn op dezelfde PC, anders moet je een draadje trekken.
Verwijder je Uno even van de setup (Tx en Rx los trekken). Daarna de Mega sketch tijdelijk aanpassen (#define UNOSERIAL Serial
) en je kunt de Mega code testen met de seriale monitor; je kunt precies het zelfde formaat gebruiken
<waarde1,waarde2,waarde3,waarde4>
Als dat goed werkt kun je de boel terug zetten en weet je dat het probleem aan de Uno kant zit. Dan kun je me de laatste versie van de Uno sketch laten zien.
kijk eens naar serialtransfer (dat is een library voor bijna alle soorten comms
nou het rare is dat alles goed aangesloten is. en zet ik handmatig een waarde in de floats gaat hij prima maar zodra ik de floats uit de sensoren lees gaat het mis en krijg ik bij de ontvanger dus NAN als waarde geprint. maar bij de uno zie je dan dus wel de waardes goed afgedrukt op de serialmonitor
dit is zender de uno;
<
//Libraries
#include <DHT.h>;
#include <SoftwareSerial.h>
//int LDRInput=A0; //Set Analog Input A0 for LDR.
//pinMode (LDRInput,INPUT);
//Constants
const int raamopen_pin = 7;
const int raamdicht_pin = 8;
const int ventilator_pin = 9;
//pinMode(10, OUTPUT);
//inMode(11, OUTPUT);
#define DHTbuitenPIN 2 // what pin we're connected to
#define DHTbuitenTYPE DHT22 // DHT 22 (AM2302)
DHT dhtbuiten(DHTbuitenPIN, DHTbuitenTYPE); //// Initialize DHT sensor for normal 16mhz Arduino
#define DHTkasPIN 3 // what pin we're connected to
#define DHTkasTYPE DHT22 // DHT 22 (AM2302)
DHT dhtkas(DHTkasPIN, DHTkasTYPE); //// Initialize DHT sensor for normal 16mhz Arduino
int LDRInput=A0; //Set Analog Input A0 for LDR.
unsigned long tempMillis;
unsigned long dnMillis;
unsigned long serialMillis;
// funties
void temperaturen();
void display(String currState);
void dagnacht();
void raamstate(String currState);
void serial(); //com
//Variables
int chk;
float humbuiten; //Stores humidity value
float tempbuiten; //Stores temperature value
float humkas; //Stores humidity value
float tempkas; //Stores temperature value
float dn;
float rs;
float tempC = 0; //com
char text[20] ; //com
char charVal[6]; //com
void setup()
{
pinMode(LDRInput,INPUT);
pinMode(raamopen_pin, OUTPUT);
pinMode(raamdicht_pin, OUTPUT);
pinMode(ventilator_pin, OUTPUT);
//pinMode(10, OUTPUT);
//pinMode(11, OUTPUT);
Serial.begin(9600);
dhtbuiten.begin();
dhtkas.begin();
//tempMillis = millis();
//dnMillis = millis();
}
void loop()
{
// temperaturen();
// dagnacht();
// raamstate();
serial();
}
void temperaturen()
{
static unsigned long tempMillis = millis();
if (millis() - tempMillis > 5000)
{//Read data and store it to variables hum and temp
humbuiten = dhtbuiten.readHumidity();
tempbuiten = dhtbuiten.readTemperature();
//Print buiten temp and humidity values to serial monitor
//Serial.print("Humidity buiten: ");
//Serial.print(humbuiten);
//S/erial.print(" %, Temp buiten: ");
//Serial.print(tempbuiten);
//Serial.println(" Celsius");
humkas = dhtkas.readHumidity();
tempkas = dhtkas.readTemperature();
//Print kas temp and humidity values to serial monitor
//Serial.print("Humidity kas: ");
//Serial.print(humkas);
//Serial.print(" %, Temp kas: ");
//Serial.print(tempkas);
//Serial.println(" Celsius");
tempMillis = millis();
}
//}
else
{
void loop();
}
}
void dagnacht()
{
static unsigned long dnMillis = millis();
if (millis() - dnMillis > 50000)
{
int value=analogRead(LDRInput);//Reads the Value of LDR(light).
Serial.println("LDR value is :");//Prints the value of LDR to Serial Monitor.
Serial.println(value);
if(value<300)
{
dn = 1;
Serial.println(dn);//The LED turns ON in Dark.
Serial.println("nacht");
}
else
{
dn = 2;
Serial.println(dn);
Serial.println("dag");//The LED turns OFF in Light.
}
//
}
else
{
loop();
}
}
void raamstate()
{
static unsigned long raamMillis = millis();
static uint16_t raamdelay;
enum class raamstate : uint8_t
{
open, //default 0
dicht, // default 1
ventilatie, // default 2
warmenacht, // default 3 }
}
//static raamstate currState = raamstate::dicht;
static currState = raamstate::dicht;
switch (currState) {
case raamstate::dicht:
//Serial.println ("raam dicht");
if (millis() - raamMillis > 5000 && tempkas > 25 && dn == 2 && rs != 1)
{
rs = 1;
Serial.println("Raam gaat open");
digitalWrite(7, HIGH);
Serial.println("ventilator aan");
digitalWrite(9, HIGH);
delay (5000);
digitalWrite(7, LOW);
Serial.println("Raam open");
currState = raamstate::open;
raamMillis = millis();
}
else if (millis() - raamMillis > 5000 && humkas > 50 && dn == 2 && rs != 1)
{
rs = 1;
Serial.println("raam gaat naar ventilatie");
digitalWrite(7, HIGH);
Serial.println("ventilator aan");
digitalWrite(9, HIGH);
delay (2000);
digitalWrite(7, LOW);
Serial.println("Raam op ventilatie");
currState = raamstate::ventilatie;
raamMillis = millis();
}
else if (millis() - raamMillis > 5000 && humkas > 50 && tempbuiten > 25 && dn == 1 && rs != 1)
{
rs = 1;
Serial.println("raam gaat naar ventilatie");
digitalWrite(7, HIGH);
delay (2000);
digitalWrite(7, LOW);
Serial.println("Raam op ventilatie");
currState = raamstate::ventilatie;
raamMillis = millis();
}
else if (millis() - raamMillis > 5000 && tempkas > 25 && tempbuiten > 25 && dn == 1 && rs != 1)
{
rs = 1;
Serial.println("raam gaat open");
digitalWrite(7, HIGH);
delay (5000);
digitalWrite(7, LOW);
Serial.println("Raam open");
currState = raamstate::open;
raamMillis = millis();
}
break;
case raamstate::open:
//Serial.println ("raam open");
if (millis() - raamMillis > 5000 && tempkas < 25 && rs != 2)
{
rs = 2;
Serial.println("raam gaat dicht");
digitalWrite(8, HIGH);
Serial.println("ventilator uit");
digitalWrite(9, LOW);
delay (5000);
digitalWrite(8, LOW);
Serial.println("Raam dicht");
raamMillis = millis();
currState = raamstate::dicht;
}
else
{
if (millis() - raamMillis >5000 && dn == 1 && rs != 2 && tempbuiten < 25)
{
rs = 2;
Serial.println("raam gaat dicht ivm nacht");
digitalWrite(8, HIGH);
Serial.println("ventilator uit");
digitalWrite(9, LOW);
delay (5000);
digitalWrite(8, LOW);
Serial.println("Raam dicht");
raamMillis = millis();
currState = raamstate::dicht;
}
}
break;
case raamstate::ventilatie:
//Serial.println("ventilatie");
if (millis() - raamMillis > 5000 && humkas < 50 and tempkas < 25 && rs != 3)
{
rs = 3;
Serial.println("raam van ventilatie naar dicht");
digitalWrite(8, HIGH);
Serial.println("ventilator uit");
digitalWrite(9, LOW);
delay (2000);
digitalWrite(8, LOW);
Serial.println("Raam dicht");
currState = raamstate::dicht;
raamMillis = millis();
}
else if (millis() - raamMillis > 5000 && humkas >50 and tempkas > 25 && dn == 2 && rs != 3)
{Serial.println("raam van ventilatie naar open");
digitalWrite(7, HIGH);
Serial.println("ventilator aan");
digitalWrite(9, HIGH);
delay (3000);
digitalWrite(3, LOW);
Serial.println("Raam open");
currState = raamstate::open;
raamMillis = millis();
}
else if (millis() - raamMillis >5000 && dn == 1 && rs != 3 && tempbuiten < 25)
{
rs = 3;
Serial.println("raam gaat dicht ivm nacht");
digitalWrite(8, HIGH);
Serial.println("ventilator uit");
digitalWrite(9, LOW);
delay (5000);
digitalWrite(8, LOW);
Serial.println("Raam dicht");
raamMillis = millis();
currState = raamstate::dicht;
}
break;
}
}
void serial()
{
static unsigned long serialMillis = millis();
if (millis() - serialMillis > 5000)
{
// humbuiten = (34.1);
// tempbuiten = (18.9);
humkas = (34.20);
tempkas = (18.90);
humbuiten = dhtbuiten.readHumidity();
tempbuiten = dhtbuiten.readTemperature();
delay(1000);
Serial.print("<");
Serial.print(humbuiten);
Serial.print(",");
Serial.print(tempbuiten);
Serial.print(",");
Serial.print(humkas);
Serial.print(",");
Serial.print(tempkas);
Serial.print(">");
serialMillis = millis();
}
else
{
void loop();
}
}
>
dit de ontvanger de mega;
<float humbuiten = 00.0;
float tempbuiten = 00.0;
float humkas = 00.0;
float tempkas = 00.0;
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use when parsing
#define UNOSERIAL Serial1
// variables to hold the parsed data
//char messageFromPC[numChars] = {0};
//int integerFromPC = 0;
//
float lm35V = 00.0;
float tempC = 00.0;
float buiten = 00.0;
float binnen = 00.0;
boolean newData = false;
//============
//Receiver code
// #include <SoftwareSerial.h>
// SoftwareSerial link(2, 3); // Rx, Tx
//#include <Serial1.h>
byte greenLED = 12;
char cString[20];
byte chPos = 0;
byte ch = 0;
char dataStr[6];
void setup()
{
Serial.begin(9600); //setup software serial
UNOSERIAL.begin(9600);
pinMode(greenLED, OUTPUT);
Serial.println("This demo expects 3 pieces of data - text, an integer and a floating point value");
Serial.println("Enter data in this style <HelloWorld, 12, 24.7> ");
Serial.println();
}
//============
void loop()
{
recvWithStartEndMarkers();
if (newData == true)
{
strcpy(tempChars, receivedChars);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with \0
parseData();
showParsedData();
newData = false;
}
}
//============
void recvWithStartEndMarkers()
{
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (UNOSERIAL.available() > 0 && newData == false)
{
rc = UNOSERIAL.read();
if (recvInProgress == true)
{
if (rc != endMarker)
{
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars)
{
ndx = numChars - 1;
}
}
else
{
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker)
{
recvInProgress = true;
}
}
}
//============
void parseData()
{
Serial.print(F("Received: "));
Serial.println(tempChars);
// split the data into its parts
char* strtokIndx; // this is used by strtok() as an index
// strtokIndx = strtok(tempChars,","); // get the first part - the string
// strcpy(lm35V, strtokIndx); // copy it to messageFromPC
strtokIndx = strtok(tempChars, ","); // this continues where the previous call left off
lm35V = atof(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
>
RS485 en JSON, eenvoudiger gaat het echt niet worden.
{"Adres":2, "tempkas": 18.90, "humbuiten": 95.3, "tempbuiten": 5.45}
Adres:2 is bij mij node 2 die antwoord op deze vraag van de master
{"Adres":2, "Temperatuur": "?"}
Uiteindelijk verstuur je 4 objecten. Met deserialize haal je dat weer uit elkaar. Waarom het wiel terug uitvinden?
DynamicJsonDocument root(400);
Serial.print("Fout: ");
Serial.println(fout.c_str());
JsonObject result = root.as<JsonObject>();
for (JsonObject::iterator it = result.begin(); it != result.end(); ++it) {
sKey = it->key().c_str();
if (sKey.equalsIgnoreCase("tempkas")) {
fltTempkas = result[sKey].as<float>();
Serial.print("Temp kas: ");
Serial.println(fltTempkas);
}
else if (sKey.equalsIgnoreCase("humbuiten")) {
fltHumBuiten = result[sKey].as<float>();
Serial.print("Hum buiten: ");
Serial.println(fltHumBuiten);
}
}
Waarom RS485 en geen RS232/UART? Bij RS485 heb je geen GND koppeling nodig. Dit zorgt er voor dat er geen groundloop kan bestaan. Het is speciaal gemaakt om onder andere de communicatie te verzorgen tussen machines en hun onderdelen. Zeker als er een wat langere afstand in het spel is.