Hardware Serial statt Software Serial nutzen...

Hallo zusammen,

ich bin noch absoluter Einsteiger und versuche jetzt schon seid einiger Zeit mir Wissen anzueignen, wie ich ein Sketch was Sowohl Hardware als auch Software Serial verwendet, so umzuschreiben, das auf dem Arduino Mega 2560 nur Hardware Serial 0 und 2 verwendet wird.

Ganz ehrlich ich verstehe es nicht...

Es geht um ein GSM/GPS Modul mit SIM808, ich habe schon SMS versendet, aber über die fertigen beispiele die Softwareserial nutzen.

Was mich als Anfänger dabei verwirrt sind die vielen Dateien die genutzt werden um die Funktionen unterzubringen.

#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>

#define MESSAGE_LENGTH 160
char message[MESSAGE_LENGTH];
int messageIndex = 0;
char MESSAGE[300];
char lat[12];
char lon[12];
char wspeed[12];

char phone[16];
char datetime[24];

#define PIN_TX 10
#define PIN_RX 11
SoftwareSerial mySerial(PIN_TX,PIN_RX);
DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,

void sendSMS();
void getGPS();
void readSMS();

void setup()
{
  mySerial.begin(9600);
  Serial.begin(9600);

  //******** Initialize sim808 module *************
  while(!sim808.init())
  {
      Serial.print("Sim808 init error\r\n");
      delay(1000);
  }
  delay(3000);

  Serial.println("SIM Init success");
      
  Serial.println("Init Success, please send SMS message to me!");
}

void loop()
{
  //*********** Detecting unread SMS ************************
   messageIndex = sim808.isSMSunread();

   //*********** At least, there is one UNREAD SMS ***********
   if (messageIndex > 0)
   { 

      readSMS();
      getGPS();
      sendSMS();
  
      //************* Turn off the GPS power ************
      sim808.detachGPS();

      Serial.println("Please send SMS message to me!");
   }
}

void readSMS()
{
  Serial.print("messageIndex: ");
  Serial.println(messageIndex);
  
  sim808.readSMS(messageIndex, message, MESSAGE_LENGTH, phone, datetime);
             
  //***********In order not to full SIM Memory, is better to delete it**********
  sim808.deleteSMS(messageIndex);
  Serial.print("From number: ");
  Serial.println(phone);  
  Serial.print("Datetime: ");
  Serial.println(datetime);        
  Serial.print("Recieved Message: ");
  Serial.println(message);
}

void getGPS()
{ 
  while(!sim808.attachGPS())
  {
    Serial.println("Open the GPS power failure");
    delay(1000);
  }
  delay(3000);

  Serial.println("Open the GPS power success");
    
  while(!sim808.getGPS())
  {
    
  }

  Serial.print(sim808.GPSdata.year);
  Serial.print("/");
  Serial.print(sim808.GPSdata.month);
  Serial.print("/");
  Serial.print(sim808.GPSdata.day);
  Serial.print(" ");
  Serial.print(sim808.GPSdata.hour);
  Serial.print(":");
  Serial.print(sim808.GPSdata.minute);
  Serial.print(":");
  Serial.print(sim808.GPSdata.second);
  Serial.print(":");
  Serial.println(sim808.GPSdata.centisecond);
  Serial.print("latitude :");
  Serial.println(sim808.GPSdata.lat);
  Serial.print("longitude :");
  Serial.println(sim808.GPSdata.lon);
  Serial.print("speed_kph :");
  Serial.println(sim808.GPSdata.speed_kph);
  Serial.print("heading :");
  Serial.println(sim808.GPSdata.heading);
  Serial.println();

  float la = sim808.GPSdata.lat;
  float lo = sim808.GPSdata.lon;
  float ws = sim808.GPSdata.speed_kph;

  dtostrf(la, 4, 6, lat); //put float value of la into char array of lat. 4 = number of digits before decimal sign. 6 = number of digits after the decimal sign.
  dtostrf(lo, 4, 6, lon); //put float value of lo into char array of lon
  dtostrf(ws, 6, 2, wspeed);  //put float value of ws into char array of wspeed

  sprintf(MESSAGE, "Latitude : %s\nLongitude : %s\nWind Speed : %s kph\nMy Module Is Working. Mewan Indula Pathirage. Try With This Link.\nhttp://www.latlong.net/Show-Latitude-Longitude.html\nhttp://maps.google.com/maps?q=%s,%s\n", lat, lon, wspeed, lat, lon);
}

void sendSMS()
{
  Serial.println("Start to send message ...");
  
  Serial.println(MESSAGE);
  Serial.println(phone);
  
  sim808.sendSMS(phone,MESSAGE);
}

Das oben ist das eigendliche Programm und ich bin jetzt an der folgenden Stelle hängen geblieben in der sim808.cpp wo ich denke das man da irgendwie übergeben muss welche Serial genutzt wird:

#include "sim808.h"

//SoftwareSerial *serialSIM808 = NULL;

Stream *serialSIM808 = NULL;

/*
void  sim808_init(void * uart_device, uint32_t baud)
{
    serialSIM808 = (SoftwareSerial*)uart_device;
	  serialSIM808->begin(baud);
}

*/

void  sim808_init(void * uart_device, char num)
{
    if(num)
		serialSIM808 = (HardwareSerial*)uart_device;
	else
		serialSIM808 = (SoftwareSerial*)uart_device;
}

Ich habe bisher noch nirgendwo raus finden können, was die Sterne bedeuten in dem Code, bis auf den stern bei */ natürlich.

Was ich einfach nicht verstehe, wie und an welcher Stelle wird das ganze umgesetzt, das die Software Serial genutzt wird und wie kann ich das ganze SoftwareSerial rausnehmen um z.b. HardwareSerial 2 zu verwenden?

#define PIN_TX 10
#define PIN_RX 11
SoftwareSerial mySerial(PIN_TX,PIN_RX);
DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,

meine Vermutung ist, das genau an der stelle ich etwas verändern muss und ich probierte es mit:

//#define PIN_TX 10
//#define PIN_RX 11
//SoftwareSerial mySerial(PIN_TX,PIN_RX);
DFRobot_SIM808 sim808(&Serial2);//Connect RX,TX,PWR,

jedoch ohne Erfolg und mit einem Fragezeichen über dem Kopf, was das & Symbol wohl für eine Wirkung haben könnte...

Ok, ich weiß jetzt mittlereile das * und & Zeigeroperatoren sind, also werde ich in die Richtung mich weiter einlesen, aber ich würde mich bitte sehr über etwas Hilfe freuen, schneller mit meinem Problem zu einer Lösung zu kommen, denn es übersteigt eindeutig leider noch meinen Horizont und müsste meiner meinung nach so einfach zu lösen zu sein, das ich es einfach nicht sehe...

Ich habe wirklich viele Artikel und Tutorials gelesen, aber was bei dem SIM808 Code gemacht wird, das habe ich so in der form noch nicht gefunden...

Vielen Dank für euer Verständniss

Mit freundlichen Grüßen

Cali

Der Teil ist doch leicht verständlich:

void  sim808_init(void * uart_device, char num)
{
    if(num)
 serialSIM808 = (HardwareSerial*)uart_device;
 else
 serialSIM808 = (SoftwareSerial*)uart_device;
}

Wenn num 0 ist wird ein Cast auf SoftwareSerial gemacht und wenn num ungleich 0 ist wird ein Cast auf HardwareSerial gemacht.

Ein void* Zeiger ist eine Art Platzhalter Datentyp. Dem kannst du alles übergeben, aber damit den Zeiger verwenden kann muss man ihn auf einen richtigen Datentyp casten

Das kann aber nicht gehen (ist auch auskommentiert. Vielleicht aus einer früheren Version):

Stream *serialSIM808 = NULL;

serialSIM808->begin(baud);

serialSIM808 ist ein Zeiger auf Stream (das ist die Klasse von der beide Serial Klassen abgeleitet sind). Die Stream Klasse hat aber keine begin() Methode. Die begin() Methode ist jeweils in den Unterklassen selbst definiert und nicht virtuell. Sie kann also nicht über einen Zeiger auf die Oberklasse aufgerufen werden.
Selbst wenn das gehen würde könnte man sich den void-Zeiger sparen und gleich einen Zeiger auf Stream übergeben

Dann musst du suchen wo die sim808_init() Methode aufgerufen wird. Und da gibt es zwei Konstruktoren:

DFRobot_SIM808(HardwareSerial *mySerial);
DFRobot_SIM808(SoftwareSerial *mySerial);

Einen für HardwareSerial und einen für SoftwareSerial. Also beim erstellen des Objekts einfach eine Instanz von HardwareSerial übergeben und schon geht es. Das ist was du hier machst:

DFRobot_SIM808 sim808(&mySerial);

Statt &mySerial machst du &Serial1 oder &Serial2 Der Compiler merkt das was du übergibst und ruft dann den entsprechenden Konstruktor auf

Serial solltest du nicht nehmen. Das ist die normale USB Schnittstelle. Dass diese nicht belegt wird ist der Grund weshalb man da normal SoftwareSerial verwendet

Vielen Herzlichen Dank für deine Erklärungen Serenifly,

jetzt weiß ich das es sich doch lohnen könnte das ich mir ein Buch über C hole, um mehr über Objekte, Klassen und das alles zu lernen. :slight_smile:

Ein bischen Stolz bin ich trotzdem, das ich ganz ganz kurz davor stand mein Problem alleine zu lösen, aber so habe ich wieder mehr erfahren. :slight_smile:

Übrigends lag das daran das ich schon im Code das richtig hatte, aber dummerweise vergessen hatte, von Pin 10 und 11 auf 16 und 17 umzustecken. :slight_smile:

Aber dank der Schnellen Hilfe, werde ich sicher noch die ein oder andere frage Stellen, damit ich mein Projekt verwirklichen kann.

Viele Grüße

Cali

Cali_X:
jetzt weiß ich das es sich doch lohnen könnte das ich mir ein Buch über C hole, um mehr über Objekte, Klassen und das alles zu lernen.

Das ist C++. Nicht C. C ist eine Untermenge von C++, aber hat keine Objekte und Klassen