Hallo,
ich versuche eine lib zu schreiben, die SoftwareSerial verwendet. Nach etlichem Probieren bin ich zumindest soweit, dass der Compiler keinen Fehler mehr meldet, aber die Schittstelle wird trotzdem nicht richtig initialisiert.
Mein Code ist folgender:
/* Sketch
* Arduino Duemilanove
Zeichen über SoftwareSerial senden
*/
#include "SOSE.h"
SOSE sose;
unsigned long timer;
void setup() {
Serial.begin(115200);
}
void loop() {
if (millis() - timer > 1000) {
sose.send();
sose.receive();
timer = millis();
}
}
Die Header-Datei
// SOSE.h
#ifndef SOSE_H
#define SOSE_H
#include <Arduino.h>
#include <SoftwareSerial.h>
class SOSE {
public:
SOSE();
~SOSE();
void send();
void receive();
};
#endif
Und die cpp:
// SOSE.cpp
#include "SOSE.h"
const byte LED_PIN = 13;
char stack[] = {"ABCD12abcd"};
SoftwareSerial softse(10, 11);
SOSE::SOSE() {
pinMode(LED_PIN, OUTPUT); //make that pin an OUTPUT
softse.begin(9600);
}
SOSE::~SOSE() {
/*nothing to destruct*/
}
void SOSE::send() {
static byte i;
Serial.println(" ");
while (i < 10) {
softse.write(stack[i]);
Serial.print(stack[i]);
Serial.print(" ");
i++;
digitalWrite(LED_PIN, HIGH);
}
i = 0;
digitalWrite(LED_PIN, LOW);
Serial.println(" ");
}
void SOSE::receive() {
while (softse.available()) {
Serial.write(softse.read());
}
}
Kann mir jemand helfen, wie man das richtig macht?
Ich hatte die Funktionen vorher in einem Sketch ausprobiert, da hat es geklappt.
Besten Dank und Grüße
mach dir keine harte Abhängigkeit zu SoftwareSerial.
Übergib deiner Klasse eine Referenz auf ein Objekt der Stream Klasse.
hier hast du ein Muster wie ich das lösen würde:
Mein Ansatz basiert auf Serial Input Basic, gepackt in eine Klasse für das Gerät.
/*
Serial Eheim
Serial Receive Example for a fix length telegram with 4 start flags
Valid telegram
56 AB 56 02 01 02 03 ...
56 AB 56 02 start flag / start marker
01 02 03 ... 112 + 47 bytes
based on a discussion in: https://forum.arduino.cc/t/daten-aus-einer-serieller-schnittstelle-auslesen-auswerten/1073809/4
by noiasca
2023-01-06
*/
class Device {
…
dann kannst du "ALLES" nehmen (alles was von Stream erbt), SoftSerial, HW-Serial, Alt-Serial.
(in der Sache,
dein aktuells Problem ist vermutlich der Aufruf von
softse.begin(9600);
im Konstruktor. Das soll erst im setup() passieren. Du legst aber dein sose objekt global an.
Kaboom.
)
karl_napp:
softse.begin(9600);
Gibt einen Grund für SoftwareSerial::begin(), der gilt auch für deine SOSE : Der Konstruktor eines globalen Objekts kommt zu früh dran.
Ich würde eine Methode
SOSE::begin(unsigned long baud) {softse.begin(baud);}
dazu erfinden und die in setup aufrufen.
Eigentlich kann/sollte da auch pinMode rein und du kommst mit einem default Konstruktor aus.
Besten Dank für die Tipps.
@noiasca :
Als Laie habe ich es leider noch nicht so mit der Objektorientierung.
@michael_x :
Das hat geholfen.
Wenn es sonst noch jemanden interessiert, sieht es jetzt folgendermaßen aus:
Im Sketch:
#include "SOSE.h"
SOSE sose;
void setup() {
Serial.begin(115200);
sose.begin(9600);
}
h-File:
class SOSE {
public:
SOSE();
~SOSE();
void begin(unsigned long baud);
void send();
void receive();
};
cpp-File:
SoftwareSerial softse(10, 11);
SOSE::SOSE() {
}
SOSE::~SOSE() {
}
void SOSE::begin(unsigned long baud) {
softse.begin(baud);
pinMode(LED_PIN, OUTPUT);
}
Nochmals vielen Dank.
combie
January 11, 2023, 4:48pm
5
Ein paar Antworten auf Stilfragen, welche du nicht gestellt hast:
Nein, durchgehend groß geschriebenen Bezeichner sind defines vorbehalten. Bei eigenen Typen wird nur der erste Buchstabe groß geschreiben. Oder/und Kamelhöckerschreibweise.
Wenn möglich, nicht in *.h und *.cpp aufteilen, sondern *.h only
Der moderne Include Guard ist: #pragma once
Entkoppeln, entkoppeln und nochmal: Entkoppeln!