SoftwareSerial data overzetten werkt niet

algemene C code
Berichten: 78
Geregistreerd: 03 Okt 2014, 17:16

SoftwareSerial data overzetten werkt niet

Berichtdoor ilioSS » 29 Sep 2019, 10:59

Goede dag,
Graag zou ik mijn project willen afronden maar ik blijf steken op een wel heel knullig punt. nl. het overzetten van data via de SoftwareSerial.
Mijn project is het registreren, alarmeren en loggen van aardschokken dmv een sensor ADXL-345 en Arduino boards.
Mijn hardware ziet er als volgt uit;
1) NANO met nRF24 radio en ADXL-345 sensor.
2) NANO met nRF24 radio deze ontvangt te zien op de serial monitor de volgende data <2,-5,6> zeg drie keer per seconde lijkt mij OK.
3) MEGA met Display, SD, RTC dit om data te verwerken en op te slaan. Nu wil ik de data via een Software serial overzetten van de NANO naar de MEGA dit lukt mij echter niet?
Zie onder voor de scripts.
Zou iemand mij op het juist spoor kunnen zetten. Dus ook de int. data in de MEGA <2,-5,6> om te loggen
Ontvangen en serial ender naar de MEGA
// ONTVANGER NODE, RF24 SENSOR NETWERK
// PROGRAMMEERVOORBEELD BITS & PARTS, WWW.BITSANDPARTS.EU
// included with software serial

#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>

// we definieeren de structuur van het te ontvangen bericht (het envelopje met daarin de gegevens)
struct sensor_bericht
{
// unsigned long ms; // de huidige tijd in milliseconden
// int sensor_waarde; // de uitgelezen sensor-waarde
// int sensor_waarde1;
// int sensor_waarde2;
int X_out;
int Y_out;
int Z_out;
};
#include <SoftwareSerial.h>

SoftwareSerial mySerial(1, 0); // RX, TX


RF24 radio(9,10); // nRF24L01(+) transceiver aangesloten met pins 9 en 10
RF24Network network(radio); // netwerk definiëren

const uint16_t deze_node = 0; // adres van onze (ontvanger) node
const uint16_t andere_node = 1; // adres van de andere (sensor) node




void setup(void)
{
Serial.begin(4800);//57600

SPI.begin();
radio.begin();
network.begin(/*kanaal*/ 90, /*node adres*/ deze_node);

Serial.println("Sensor netwerk ontvanger start...");


mySerial.begin(4800);
while (!Serial) {
;
}

Serial.print("Good day Theo");

mySerial.begin(4800);
mySerial.println("Hello, Holwerd");
}


//*******************************************************************************
// HOOFD LOOP
//*******************************************************************************
void loop(void)
{
Serial.begin(4800);
mySerial.begin(4800);
int X_out;
int Y_out;
int Z_out;

// houdt het netwerk aan de gang
network.update();

// is er data beschikbaar op het netwerk voor ons?
while ( network.available() )
{
// zo ja, pak de data en print het

// we geven aan dat 'header' de structuur heeft van 'RF24NetworkHeader' (voorgedefinieerd in de RF24network library)
RF24NetworkHeader header;

// we geven aan dat 'bericht' de structuur heeft van 'sensor_bericht'
sensor_bericht bericht;

// we lezen het bericht van het netwerk
network.read(header,&bericht,sizeof(bericht));
X_out = bericht.X_out;
Y_out = bericht.Y_out;
Z_out = bericht.Z_out;
// de ontvangen gegevens die in het sensor bericht zaten printen
// Serial.print(" Sensor waarde: ");
Serial.print(254);
Serial.print(X_out);
Serial.print(255);
Serial.println(Y_out);
// Serial.print(",");
// Serial.print(Z_out);
// Serial.println(">");

}
}

MEGA serial ontvanger
/*
* MEGA voor aardschok met serial extra NANO met serial voor de i2c sensor
*
*/
//******************************** algemeen ******************************
#include <SPI.h>
#include "Wire.h"
#include <EEPROM.h>
#include <Wire.h>
//*************************Klok*****************************************
#define DS3231_I2C_ADDRESS 0x68 // I2C
byte decToBcd(byte val) // Convert normal decimal numbers to binary coded decimal uit klok signaal?????
{
return( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val) // Convert binary coded decimal to normal decimal numbers uit klok signaal ???????
{
return( (val/16*10) + (val%16) );
}

//****************************ALGEMEEN ****************************************

//*******************************DISPLAY***********************************
#include <LiquidCrystal.h>


// this is factory config shield initialisation
LiquidCrystal lcd(8,9,4,5,6,7);

//**********************************DISPLAY********************************

int dd;
int mm;
int yy;
int hr;
int mi;
int se;
int dayOfMonth;
int dag;
int mem = 0;// in eeprom om dag te kunnen onderschijden
int addr = 0;
//*********************SD*********************************
#include <SD.h>
const int chipSelect = 53; // was 4???en 10 nu 53 ivm mega
File dataFile;
File filename;


//*******************************SOFTWARE SERIAL********************************************
#include <SoftwareSerial.h>

SoftwareSerial mySerial (0, 1); // RX, TX voor de MEGA

// we definieeren de structuur van het te sturen bericht (het envelopje met daarin de gegevens)
struct sensor_bericht
{
int X_out;
int Y_out;
int Z_out;
};


void setup()
{
SPI.begin();
Wire.begin();
Serial.begin(19200);

//********************Klok***************************
// setDS3231time(30,40,19,3,31,10,17); // uncommand en set time/date seconds, minutes, hours, day, date, month, year
//*****************************SD********************
Serial.print("Initializing SD card...");
pinMode(SS, OUTPUT);
if (!SD.begin(chipSelect))
{
Serial.println("Card failed, or not present"); // see if the card is present and can be initialized:
while (1) ; // don't do anything more: nu mag door ook als er geen kaart is
}
Serial.println("card initialized.");

lcd.begin(16,2);
lcd.clear();

lcd.setCursor(0,0);
lcd.print("Theotje hier");
delay(100);

// set the data rate for the SoftwareSerial port
mySerial.begin(19200);
mySerial.println("Hello, world?");


}

void loop(void)
{
int X_out;
int Y_out;
int Z_out;
// int Z_out;
Serial.begin(19200);
sensor_bericht bericht = {X_out, Y_out, Z_out};
delay(10);
displayTime(); // om tijd uit te lezen en op display te zetten???????
delay(10);
mem = EEPROM.read(addr); // geheugen uitlezen naar mem

mySerial.begin(19200);
delay(100);
if (Serial.available()) {
delay(100);
X_out = (Serial.read () << 8);
Y_out = (Serial.read() <<8);
Z_out = (Serial.read() <<8);

Serial.print("X= ");
Serial.print(X_out);
Serial.print(" Y= ");
Serial.print(Y_out);
Serial.print(" Z= ");
Serial.println(Z_out);
}




if ( mem != dd ) // new file aanmaken
{
Serial.print(yy);
Serial.print("#");
Serial.print(mm);
Serial.print("#");
Serial.println(dd);
delay(50);
char filename[12];
sprintf(filename,"%02d-%02d-%02d.csv",yy,mm,dd);
delay(30);
dataFile=SD.open(filename,FILE_WRITE);
delay(30);
dataFile.println("Date,Time,");
delay(40);
dataFile.close();
Serial.print("log in nieuwe file..");
EEPROM.write(addr, dd);
Serial.println(filename);
}

else{

// if ( (mi %2 == 1) && (se == 59)) { // elke twee minuten loggen
if ( se == 59 ) { // elke 1 minuut loggen naar schijf
char filename[12];
sprintf(filename,"%02d-%02d-%02d.csv",yy,mm,dd);
dataFile=SD.open(filename,FILE_WRITE);
delay(10);
dataFile.print(yy);
dataFile.print("/");
if(mm<10){
dataFile.print("0");}
dataFile.print(mm);
dataFile.print("/");
if(dd<10){ // nullen aanvullen als datum een cijfer is
dataFile.print("0");}
dataFile.print(dd);
dataFile.print(",");
if(hr<10){
dataFile.print("0");}
dataFile.print(hr);
dataFile.print(":");
if(mi<10){
dataFile.print("0");}
dataFile.print(mi);
dataFile.print(":");
if(se<10){
dataFile.print("0");}
dataFile.println(se);

dataFile.flush();
Serial.print("log in bestaande file ");
Serial.println(filename);
dataFile.close();
// delay(800);
}
}

lcd.setCursor(0,1);
lcd.print(millis() / 1000);


}




////////////////////////////// voids///////////////////////////

void displayTime()
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, // retrieve data from DS3231
&year);

if (hour<10)
{
Serial.print("0");
}
Serial.print(hour, DEC); // send it to the serial monitor
Serial.print(":");
if (minute<10) // om nullen in te voeren by single cijfer
{
Serial.print("0");
}
Serial.print(minute, DEC);
Serial.print(":");
if (second<10)
{
Serial.print("0");
}
Serial.print(second, DEC);
Serial.print(" ");
Serial.print("20");
Serial.print(year, DEC);
Serial.print("/");
Serial.print(month, DEC);
Serial.print("/");
Serial.println(dayOfMonth, DEC);
// Serial.print(" Dag v/d week: ");
delay(20);
dd=(dayOfMonth);
mm=(month);
yy=(year);
hr=(hour);
mi=(minute);
se=(second);
dag=dayOfWeek;
}


void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year)
{
Wire.beginTransmission(DS3231_I2C_ADDRESS); // sets time and date data to DS3231
Wire.write(0); // set next input to start at the seconds register
Wire.write(decToBcd(second)); // set seconds
Wire.write(decToBcd(minute)); // set minutes
Wire.write(decToBcd(hour)); // set hours
Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
Wire.write(decToBcd(month)); // set month
Wire.write(decToBcd(year)); // set year (0 to 99)
Wire.endTransmission();
}

void readDS3231time(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0); // set DS3231 register pointer to 00h
Wire.endTransmission();
Wire.requestFrom(DS3231_I2C_ADDRESS, 7); // request seven bytes of data from DS3231 starting from register 00h
*second = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*hour = bcdToDec(Wire.read() & 0x3f);
*dayOfWeek = bcdToDec(Wire.read());
*dayOfMonth = bcdToDec(Wire.read());
*month = bcdToDec(Wire.read());
*year = bcdToDec(Wire.read());
}

Advertisement

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: SoftwareSerial data overzetten werkt niet

Berichtdoor Koepel » 29 Sep 2019, 16:01

1) SoftwareSerial werkt vaak niet samen met andere code
Volgens mij is de SoftwareSerial is geen oplossing als er een seriële poort nodig is, vanwege de vele problemen.
Het is mooi dat het bestaat, maar de SoftwareSerial is de allerlaatste (en allerslechtste) keuze om een seriële poort toe te voegen.
SoftwareSerial vraagt zoveel van een eenvoudig Arduino board, dat er niet veel meer mogelijk is.
Het is dus goed mogelijk dat je RF24 communicatie niet samengaat met de SoftwareSerial op het Nano board.

2) Pin 0 en 1 zijn al in gebruik
Bij de Nano en de Mega zijn pin 0 en 1 al in gebruik door de hardware seriële poort. Die wordt gebruikt om een sketch te uploaden en voor de seriële monitor. Gebruik andere pinnen.

3) De Arduino Mega heeft drie vrije hardware seriele poorten
De SoftwareSerial is een hele slechte oplossing, en het is op de Mega niet nodig.
Gebruik dus geen SoftwareSerial zolang de Mega nog een vrije (hardware) seriële poort heeft.
https://www.arduino.cc/reference/en/language/functions/communication/serial/
Je kunt "Serial1", "Serial2" en "Serial3" op dezelfde manier gebruiken, zoals je "Serial" gebruikt.

4) Gebruik code-tags.
Als je een bericht plaatst op dit forum, klik dan op de knop "Code" voor de code-tags. Zet je sketch tussen die code-tags.

5) De sketch voor de Nano

5a)
De "Serial.begin()" en "mySerial.begin()" horen in setup() en niet in de loop(). Daar staan ze al, dus die in de loop() kunnen weg. De "mySerial.begin()" staat twee keer in setup(), dat moet natuurlijk gewoon één keer zijn.

6) De sketch voor de Mega

6a)
De "Serial.begin()" en "mySerial.begin()" horen in setup() en niet in de loop(). Daar staan ze al, dus die in de loop() kunnen weg.

6b)
Welke baudrate wil je ? Een Nano op 4800 baud verbinden met een Mega op 19200 baud lijkt me geen goed idee.

6c)
Dit is een bug: char filename[12];
Kun je die 40 maken in plaats van 12 ?

7)
Als je kijkt naar de minuten en seconden om iets te doen, dan zou je die seconde kunnen missen als er andere code is die langer dan een seconde duurt.
Als je met een if-statement kijkt naar de minuten en seconden, dan zou dat meerdere keren uitgevoerd kunnen worden als de loop() vaak genoeg herhaald wordt.
Het is dus nodig om dat beter te doen. Het is ook nodig om de vele onnodige delay() uit de loop() te halen.

Berichten: 78
Geregistreerd: 03 Okt 2014, 17:16

Re: SoftwareSerial data overzetten werkt niet

Berichtdoor ilioSS » 30 Sep 2019, 11:14

Hallo Koepel,

Hartelijk dank voor je uitvoerige reply.

Eerst en voor al discipline met het gebruik van de code zal ik doen en beter op letten.
Idd geeft het gebruik van SoftwareSerial problemen zoals het uploaden van een sketch in de UNO die dmv serial hardware matig is verbonden met de MEGA gaat niet. Men dient de serial verbinding los te nemen.

Wat ik uit je bericht begrijp is dat het gebruik van SoftwareSerial zowiezo af te raden is. En bovendien niet noodzakelijk omdat ik een tweede serialpoort kan gebruiken bv serial1. Ik zal dat gaan uitproberen.
Ook zal ik de overbodige Serial.begin() weglaten daar waar ze niet nodig zijn.
De delay zijn vaak proef onder vindelijk in de script gekomen zonder worden sommige instructies niet of onvolledig uitgevoerd. ( mijn ervaring)
De serial speed zal ik gelijk zetten voor alle scripts omdat als dit verschild het zowiezo niet werkt.

Ik ga aan de slag en kom retour met mijn bevindingen.
Veel dank.
Met vriendelijke groet,
ilioSS

Gebruikers-avatar
Berichten: 241
Geregistreerd: 22 Jan 2013, 16:40

Re: SoftwareSerial data overzetten werkt niet

Berichtdoor zuid » 30 Sep 2019, 17:24

Is de 2e NANO echt nodig? De nRF24 radio kan wellicht ook door de MEGA aangestuurd worden.
Afstand tussen MEGA en NANO is toch beperkt.
m.v.g. Nico

Berichten: 78
Geregistreerd: 03 Okt 2014, 17:16

Re: SoftwareSerial data overzetten werkt niet

Berichtdoor ilioSS » 30 Sep 2019, 20:31

Hallo Nico,

Hartelijk dank voor je reactie.
De nRF24 ontvanger met serial aan de MEGA hiervoor gekozen omdat de communicatie bus niet werkend te krijgen is icm de SD beide SPI. Mijn RTC zit op i2c.
Het probleem nu is dat ik het volgende moet tackelen.
de UNO nRF24 ontvanger krijgt devolgende string en lees ik uit op Serial1
<2,-9,6><2,-9,6> enz. vertegenwoordigen de sensor waardes X_out, Y_out, Z_out.

Ik zie de data binnen komen maar ben nog niet zo ver dat ik ze als int. inlezenen kan opslaan op de SD.
Probleem met de serial read etc. string enzo.
Ik zoek verder.
Ben bezig met:

if (Serial1=available())
{ Serial1read = "<"
X_out = SerialreadUntil","
Serial.print(X_out);
}
dit voor alle drie de waardes dit geeft op de Serial.monitor wel de waardes maar niet consequent (en het zijn geen int,s )opvolgend soms lijkt het dat de Serial.prinln("Z_out");
word overgeslagen.

Wat is bv een mooie manier om de sensor waardes in te lezen en om te zetten naar int,s? Veel voorbeelden op internet niet die mijn vraag dekken.

Met jullie opmerkingen en hulp gaat dat lukken. Ondertussen zoek ook ik verder.

Met vriendelijke groet,
ilioSS

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: SoftwareSerial data overzetten werkt niet

Berichtdoor Koepel » 01 Okt 2019, 00:53

De SPI-bus heeft wel eens problemen met het MISO signaal. Als een SPI module niet is geselecteerd, dan moet die module de MISO vrij laten (hoogohmig maken). Dat doen sommige modules niet, waardoor anderen geen gebruik meer van de SPI-bus kunnen maken.
Sommigen gaan zelfs op de SPI bus 3.3V en 5V door elkaar mengen.

Heeft jouw SD module een level shifter ? Het (micro)SD kaartje werkt op 3.3V terwijl jouw Arduino Mega met 5V werkt.

Je kunt beter het juiste probleem oplossen en proberen de SPI bus werkend te krijgen.
Stel dat je nu weer op een lastig probleem stuit, ga je dan weer een ingewikkelde omweg maken met een extra Arduino board ? En als dat niet lukt nog een board er bij ?
https://nl.wikipedia.org/wiki/KISS-principe


Er zijn twee oplossingen om die seriële data in te lezen:

A) Met gebruik van Arduino functies, waarbij ik een heel sip gezicht trek :(

Hier staat een lijstje van de Serial functies: https://www.arduino.cc/reference/en/language/functions/communication/serial/.
Met ReadBytesUntil() en findUntil() en parseInt() kom je een heel eind. Maar als je fouten wilt opvangen, dan wordt de code alsnog ingewikkeld. Stel dat je de derde integer wilt lezen, en er komt een '<'. Dan is het beter om de huidige data niet te gebruiken en opnieuw de drie integers te gaan inlezen. Als je dat op die manier wilt doen, dan zijn er misschien wel tientallen uitzonderingssituaties om rekening mee te houden.

B) Met ouderwetse arrays van char en eventueel sscanf :geek:

Wanneer je eerst een blok data in een array zet, dan kun je daarna met die data doen wat je wilt.
Wanneer je niet gaat wachten op het volgende karakter, maar meteen weer door gaat, dan kun je in de sketch nog meerdere dingen doen.
Dat vergt echter wel wat programmeerkennis.

Hints:
Maak een array (een buffer van char) en een variabele voor de index.
Zie je een '<' dan de index 0 maken en de '<' in het array plaatsen.
Volgende karakters in het array zetten, en index ophogen, check of het nog binnen het array past.
Zie je een '>' dan kun je een sscanf doen, een sscanf controleert of die integers ook echt gevonden zijn.
Bijvoorbeeld: if( sscanf( buffer, "<%d,%d,%d>", &x, &y, &z) == 3)
http://www.cplusplus.com/reference/cstdio/sscanf/.

Berichten: 78
Geregistreerd: 03 Okt 2014, 17:16

Re: SoftwareSerial data overzetten werkt niet

Berichtdoor ilioSS » 01 Okt 2019, 09:26

Hallo Koepel,

Hartelijk dank voor je swift en uitgebreide reactie.

IDD geeft gebruik van SPI met meerdere sensoren problemen.
De gebruikte SD kaart is die mini SD met levelshifter. Werkt prima.De SD kaart zit op de header ICSP naast de reset knop.

Het te omzeilen probleem is dat ook mijn radio nRF24 SPI gebruikt. Vandaar. Ja het is het probleem omzeilen.
Ik gebruik het SD kaartje direct aan mijn 5V ( levelshifter op miniSD kaart )
Mijn ervaringen met alles ( SD, RTC, DISPLAY, nRF24 ) op de MEGA gaf problemen. Kennelijk een hardware issue op de MISO line?
Dit uitzoeken het gedrag van de MISO lines zal niet eenvoudig met een multimeter te doen zijn?


De keus op de MEGA is dat hij alle randapparatuur zou moeten kunnen behappen. SPI noopte mij tot het gebruik van de NANO met nFR24 en serial.

KISS is wat het is zowel hardware matig als software matig, duidelijk is weer geworden dat consequent werken duidelijkheid geeft. Dank voor de hint.

Jou hint met array,s te werken ga ik eens uitzoeken en proberen.
Komt mij wel bekend voor ik ga er eens induiken om uit te vlooien en werkend te krijgen.

Ik hou je op de hoogte.
btw Nico leest ook mee die ook bedankt voor zijn input.

Met vriendelijke groet,
ilioSS

ps. Als het MISO issue getackeld is zou het mogelijk zijn om alles op de MEGA te krijgen???( SD spi, ADXL-345spi, RTC3132i2c, DISPLAYserial?)

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: SoftwareSerial data overzetten werkt niet

Berichtdoor Koepel » 01 Okt 2019, 18:24

Hoe heb je een 3.3V ADXL-345 op een 5V SPI bus aangesloten :o :?:
Voor zover ik weet heeft alleen de module van Adafruit iets. De Adafruit module heeft een soort van half-zachte manier waardoor de sensor-module op een 5V Arduino board aangesloten kan worden, zonder dat de sensor stuk gaat. Dat gaat ten koste van de maximale snelheid van de SPI bus.

Je kunt de MISO testen.
In setup() zet je de Chip Select voor die module uit, dat is hoog. Dus pinMode(...) en digitalWrite(..., HIGH).
Daarna kun je weerstandje van 1k of 4k7 met de MISO verbinden. De andere kant van de weerstand op 5V en op GND. Als het MISO signaal zonder problemen (via de weerstand) meegaat naar 5V en GND, is het hoogohmig.

Hoogohmig is goed, dan laat die module de SPI-bus vrij voor anderen als de module niet geselecteerd is.

Berichten: 78
Geregistreerd: 03 Okt 2014, 17:16

Re: SoftwareSerial data overzetten werkt niet

Berichtdoor ilioSS » 02 Okt 2019, 10:31

Hallo Koepel,

Thanks voor je reactie.
Mijn ADXL-345 zit op het boardje GY-291 met een 3,3 v regulator. De i/o SDA/SCL gaan wel ongeleveled naar de NANO.
Op de foto zie je mijn PCB met 3.3 volt reg. van de 5V USB. De 3.3V ook voor de nRF24 radio.
Het boardje werkt prima.

Ja, dan het MISO verhaal. Ga ik uitproberen zoals gezegd. Duurt wel even het geneuzel met het serial inlezen van de string naar int. heeft ook al wat tijd gekost
tot nu toe geen resultaat.

Met vriendelijke groet,
ilioSS

ps. Ik krijg de foto niet in het juiste Formaat?

Berichten: 78
Geregistreerd: 03 Okt 2014, 17:16

Re: SoftwareSerial data overzetten werkt niet

Berichtdoor ilioSS » 02 Okt 2019, 11:55

Hallo Koepel,

Net de ADXL-345 verbonden met de MEGA dus alles nu aan de MEGA en het werkt wonder boven wonder. Hoewel technisch verklaarbaar.

Ik heb de ADXL-345 via de i2c aangesloten parallel aan de RTC de SD zit op de SPI. ( MISO probleem omzeilt!)

Mijn doel is bereikt. Aardschok registeren en opslaan middels Arduino.
Blijft knagen het serieel inlezen en omzetten naar int,s.

Ook het SPI is niet getackeled mogelijk ga ik dat ook proberen.

In ieder geval hartelijk dank voor de hulp onder vonden.
1) C++ site ga ik zeker meer gebruiken
2) Scrip schoonhouden en programmeer regels naleven en documenteren
3) Volhouden
4) Weten dat er altijd een alternatief is.

Hartelijk dank,
ilioSS

Volgende

Terug naar C code

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 8 gasten