Machbarkeit?

hallo zusammen,
ich möchte auf meinem Arduino Mega mehrere Programme darauf spielen und daraus nachher ein "Multifunktionales Gerätes"machen: und zwar ein Programm für einen Rfid-Sensor(über HardwareSerial), ein Programm für einen IR_Sensor (über SoftwareSerial) und ein weiteres Programm um die Drehrichtung eines Motor zu ermitteln.
Alle Programme laufen einzeln einwandfrei.
Die Programme Für den RFID und den Motor sind mittels State-Machines realisiert worden.
Das Gerät muss sich zunächst mal im Schlafmodus befinden und wenn es aufgeweckt ist, soll es erkennen können, was eingesteckt ist und zum entsprechenden Programm springen.
ich habe versucht , das ganze in einer state Machine zu Packen, es Funktioniert allerdings nicht wie erwartet.
nun meine Fragen:
Kann man das ganze überhaupt mit einer State-Machine realisieren ? wenn nicht was wäre die bessere Alternative?
Das Gerät soll in der Lage sein zu erkennen, was gerade eingesteckt ist. Also ob ein Rfid-Sensor oder ein Motor eingesteckt ist.
wie kann man solch eine Überprüfung machen:
für den Ir-Sensor habe ich die Funktion mySerial.available() angewendet.
für den Rfid-Sensor und den Motor habe ich keine Ahnung wie man es machen soll.
Danke für jeder Tipp

Hallo,

vielleicht über eine Art Kodierpin am Modulstecker. Die Eingänge fragst du ab bzw. im Sleepmode reagierst du auf den Interrupt. Könnte ich mir aktuell vorstellen.

Doc_Arduino:
Hallo,

vielleicht über eine Art Kodierpin am Modulstecker. Die Eingänge fragst du ab bzw. im Sleepmode reagierst du auf den Interrupt. Könnte ich mir aktuell vorstellen.

Danke für den Vorschlag ,
was meinst du mit "eine Art Kodierpin"

Hi

Solltest Du bereits Software haben - dann wäre Es eine gute Idee, uns an Dieser Teil haben zu lassen.
Die Einzel-Sketche sollten nicht gleichnamige globale Variablen benutzen.

Wie Du Was 'anstecken' willst, ist mir noch nicht ganz klar - ein Motor wird wohl eine geringfügig andere Beschaltung verlangen, als ein RFID-Modul - Letzteres funktioniert, oder eben nicht - der Motor lässt den Arduino schmelzen - im Winter vll. eine Idee, aber Da ist Heizöl nun doch billiger.

MfG

pispa:
Kann man das ganze überhaupt mit einer State-Machine realisieren ?

Wenn man das überhaupt ralisieren kann, dann wird das wohl eine state machine werden.

pispa:
wenn nicht was wäre die bessere Alternative?

Alternativen?
Mir nicht bekannt.

pispa:
was meinst du mit "eine Art Kodierpin"

Drei Steckerpins verbindest Du mit digitalen Eingängen des Arduinos, wobei die Eingänge an internen PullUps hängen, unbeschaltet also HIGH liefern. Je nach angeschlossener Hardware wird ein Steckerpin mit GND verbunden, wodurch die Anwendung ausgewählt werden kann, weil einer der drei Eingänge LOW liefert.

sie benutzen keine gleichnamige globale Variablen,
und das gerät dient nachher nur zum Testen und es wird beim Testen den Motor per Hand gedreht,
also keine Gefahr zu Schmelzen.
hier mein nicht funktionierendes Programm.
ich habe Tastern benutzt, die wenn die gedrückt sind zu den jeweiligen Programmen springen soll.
die State-Machine reagiert aber nicht korrekt auf Tastendrücke

#include <RFID.h>
#include <avr/sleep.h>//this AVR library contains the methods that controls the sleep modes
#include <LiquidCrystal.h>
#include <avr/power.h>
#include<Drehrichtung.h>
#include <SoftwareSerial.h>
#define interruptPin 2 //Pin we are going to use to wake up the Arduino

LiquidCrystal lcd(12, 11, 5, 4, 3, 7);
Motor Motor (9, 8, 22);
RFID  RFID(6);
SoftwareSerial mySerial(10, 12); // RX, TX
enum State_enum {Sleep,Abfrage, Rfid_Sw_Hw,Rfid, Ir, Motorsensor, End};
byte zustand = Sleep ;
unsigned long Starttime;

void setup() {
  Serial.begin(9600);
  lcd.begin(16,2);
  mySerial.begin(1200);
  pinMode(interruptPin, INPUT_PULLUP);//Set pin d2 to input using the buildin pullup resistor
  pinMode(50, INPUT_PULLUP);
  pinMode(51, INPUT_PULLUP);
  pinMode(52, INPUT_PULLUP);
  attachInterrupt(0, wakeUp, LOW);
}
void loop() {
  States();
}

void wakeUp() {
}

unsigned char PrintBlocks() { 
  unsigned char *checkbyte;
  unsigned char Block[4];
  checkbyte = RFID.Read_Block();
  if (checkbyte == NULL)
  {
    return;
  }
  else {
    lcd.display();
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    lcd.print("Die Nutzbytes:");
    lcd.setCursor(0, 1);
    for (int i = 5; i < 9; i++) {
      Block[i] = *(checkbyte + i);
      lcd.print(Block[i], HEX);
      lcd.print(" ");
    }
  }
}

int States() {
  switch (zustand){
    case Sleep:
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);//Setting the sleep mode, in our case full sleep  
      sleep_enable();//Enabling sleep mode
      power_adc_disable();
      power_spi_disable();
      power_timer0_disable();
      power_timer2_disable();
      power_twi_disable();
      attachInterrupt(0, wakeUp, FALLING);//attaching a interrupt to pin d2
          
      sleep_mode();//activating sleep mode
//      sleep_cpu();
      zustand = Abfrage;      
      break;

    case Abfrage:
    Serial.println("Abfrage");
      if ( digitalRead(50) == LOW)
      {
        zustand = Rfid_Sw_Hw;
      }
      else if ( digitalRead(51) == LOW)
      {
        zustand = Ir;
      }
      else if ( digitalRead(52) == LOW)
      {
        zustand = Motorsensor;
      }
      else if( digitalRead(interruptPin) == LOW)
      {
        zustand = End;
      }
      break;

    case Rfid_Sw_Hw:
      lcd.display();
      lcd.begin(16, 2);
      lcd.setCursor(0, 1);
      lcd.print("Rfid_Sw_Hw");
      lcd.begin(16, 2);
      lcd.setCursor(0, 0);
      lcd.print("HW:");
      lcd.setCursor(0, 1);
      lcd.print("SW:");
      lcd.setCursor(3, 0);
      unsigned long Starttime = millis();
      if (RFID.Get_Hw_Version() > 0) {
        lcd.print(RFID.Get_Hw_Version(), HEX);
      }
      else {
        lcd.print("Fehler ");
        lcd.print(RFID.Get_Hw_Version());
      }
      lcd.setCursor(3, 1);
      if (RFID.Get_Sw_Version() > 0) {
        lcd.print("ACv");
        lcd.print(RFID.Get_Sw_Version(), HEX);
      }
      else {
        lcd.print("Fehler ");
        lcd.print(RFID.Get_Sw_Version());
      }
      zustand= Rfid;
      break;

      case Rfid:
      PrintBlocks();    
      if ( digitalRead(51) == LOW)
      {
        zustand = Ir;
      }
      else if ( digitalRead(52) == LOW)
      {
        zustand = Motorsensor;
      }
      else if( digitalRead(interruptPin) == LOW)
      {
        zustand = End;
      }
      break;

      case Ir:
      lcd.begin(16,2);
      lcd.setCursor(0, 1);
      lcd.print(telegramm());
      if ( digitalRead(50) == LOW)
      {
        zustand = Rfid;
      }
      else if ( digitalRead(52) == LOW)
      {
        zustand = Motorsensor;
      }
     
      else if( digitalRead(interruptPin) == LOW)
      {
        zustand = End;
      }
      break;

      case Motorsensor:
      Print_Motor_Infos();
      if ( digitalRead(50) == LOW)
      {
        zustand = Rfid;
      }
      else if( digitalRead(51) == LOW)
      {
        zustand = Ir;
      }  
      else if ( digitalRead(interruptPin) == LOW)
      {
        zustand = End;
      }         
      break;

      case End:
     sleep_disable(); //Disable sleep mode
      detachInterrupt(0);
      lcd.noDisplay();
      zustand = Sleep;           
      break;

  }
  
}

void Print_Motor_Infos() {
  bool *Zustand;
  bool Sensor[8];
  Zustand = Motor.Sensorzustand();
  for (int i = 0; i < 7; i++) {
    Sensor[i] = *(Zustand + i);
  }
 lcd.setCursor(0, 0);
  if (Sensor[6] == false)
    lcd.print("L");
  else lcd.print("R");
  lcd.setCursor(3, 1);
  if (Sensor[0] == true)
    lcd.print("N");
  else lcd.print(Sensor[3]);
  lcd.setCursor(6, 1);
  if (Sensor[1] == true)
    lcd.print("N");
  else lcd.print(Sensor[4]);
  lcd.setCursor(9, 1);
  if (Sensor[2] == true)
    lcd.print("N");
  else lcd.print(Sensor[5]);
}

int telegramm() {
  mySerial.begin(1200);
  byte empfangsbytes[30];
  byte Sort[20];
  int Sort1[20];
  int a = 0;
  int b = 0;
  int c = 0;
  int count = 0;
  bool Uebereistimmungen = false;
  int counter = 0;

  while (mySerial.available() < 24);
  while (b < 30) {
    empfangsbytes[b] = mySerial.read();
    b++;
  }

  for (int i = 0; i < 29; i++) {
    for (int j = 1; j < 30; j++) {
      if ((empfangsbytes[i] == empfangsbytes[j])) {
        count++;
      }
    }
    if (count >= 3)
      Uebereistimmungen = true;
    count = 0;
  }
  for ( int j = 0; j < 23; j++) {
    for ( a = j; a < j + 6; a++) {
      if ((~empfangsbytes[a], BIN) == (empfangsbytes[a + 1], BIN)) {
        counter++;
      }
      if (counter >= 5 && Uebereistimmungen == true) {
        for (int i = 0; i < 30; i++) {
          if (empfangsbytes[i] < 99 ) {
            if (empfangsbytes[i] == empfangsbytes[i + 2])
              return empfangsbytes[i];
          }
        }
      }
    }
    counter = 0;
  }
  return -1;
}

was meinst du mit "eine Art Kodierpin"

z.B. könnte das Kabel mit den Motor-Signalen den Rx Pin von deinem RFID-Serial auf LOW ziehen. Dann weißt du, dass kein Serial-Signal da ist.
Aber beim MEGA2560 hast du ja genug Pins, da ist agmues Vorschlag weniger getrickst.

michael_x:
... da ist agmues Vorschlag ...

Eher der von Doc_Arduino, ich habe nur einen Erklärungsversuch gestartet.

Hallo,

Rfid-Sensor (über HardwareSerial),
IR_Sensor (über SoftwareSerial),
Motor

Ich meinte das schon so wie agmue das in meinem Sinne weiterausgeführt hat. :wink:
Die viel größere Arbeit macht der Aufbau der "Arduino-Buchse" und der Modulstecker. Hier steckt die Hauptlogik drin. Die Pinabfrage ist dagegen einfach.

Wenn man den Faden weiterspinnt, dann würde ich für den IR eine 2. Hardware Serielle verwenden. Wenn du einen Mega hast solltest du ihn auch nutzen.

Jetzt hast du sogar die Wahl zwischen per USART aufwecken im Sleepmode für RFID und IR oder extra per Kodierpin. Hier tun sich mannigfaltige Möglichkeiten auf.

Wenn man den Faden noch weiterspinnt, kann man sogar alle Module die eine Serielle benötigen auf eine Serielle legen, da nur ein Modul gleichzeitig angesteckt sein kann. Ich weiß jetzt nicht wie schnell das aufwecken ist und wieviel Zeit bleibt zum Baudraten ändern wenn schon Daten kommen, sollte aber theoretisch funktionieren. Am Kodierpin wird erkannt welches Modul angesteckt ist und die Serielle entsprechend umkonfiguriert.

Etwas viel Theorie, aber in die Richtung würde ich Überlegungen anstellen ...

die State-Machine reagiert aber nicht korrekt auf Tastendrücke

erster Schritt: statte deinen Sketch mit entsprechenden Debug-Ausgaben auf die Serielle Schnittstelle aus, damit du zur Laufzeit erkennst, wo sich dein Code verläuft. So bist ja blind! Nach jedem IF digitalread blabla ein Serial.println(F(“ich bin jetzt dablabla”));

Hi

   Serial.print(__PRETTY_FUNCTION__);
   Serial.print(__FILE__);
   Serial.print(__LINE__);
   Serial.print(__DATE__);

Einfach Mal mit 'spielen' :slight_smile:
(ist aber auch nicht auf meinem Mist gewachsen, kommt eher von hier - hier aus dem Forum.

MfG

danke für die Tipps, ich habe soweit den pin für den Rfid Sensor Kodiert, der immer auf Gnd geht wenn angesteckt ist. Das Problem hier ist das es manchmal kurz wieder auf High geht, obwohl der Sensor angesteckt ist und somit den ganzen Ablauf durcheinander bringt.
hat Jemand eine Idee , wie man es beheben kann.
Ausserdem wenn sich die Statemachine im Zustand befindet, wo der die Rfid sensor werte erfasst, läuft es erstmal ohne Probleme und irgendwann bleibt es da hängen. Zum Testen habe ich extra keine Abfrage in diesem Zustand gemacht damit er nicht verlassen wird.
weiss da jemand woran das liegt, oder liegt es daran dass man keine state machine in einer state machine einbinden kann.
der RFid Sensor benuzt nämlich in seiner Bibliothek auch eine state machine

PS: ich wollte dazu das Programm posten, es geht aber nicht. ich bekomme die Meldung dass ich blokiert bin,weil ich schimpfwörte oder so benutzt haben soll

Ganz prinzipell geht das natürlich, sofern ... (jetzt kommen die Einschränkungen):

  • du wirklich genau verstehst, was in den einzelnen Programmen passiert. Dann kannst du sie schrittweise zu einem neuen Gesamtprogramm zusammensetzten bzw. neu schreiben. Du wirst jedoch scheitern, wenn du die Sketche nur irgendwo "gefunden" hast

  • der Speicher (insbes. RAM) des gewählten Arduino-Modells für den Code (Variablen und Arrays) und die benötigten Libs ausreicht (evtl. "größeres Modell" verwenden: Mega, Due oder ESP)

  • das gewählte Arduino-Modell genügend geeignete Pins hat

  • sich irgendwelche Interrupts nicht "in die Quere" kommen

Getreu dem Spruch: "Alles, was man beschreiben kann, kann man auch programmieren ..." ist deine Frage mit "Ja" zu beantworten. Ist nur eine Frage des Aufwandes ...

ok das Problem mit dem hängen bleiben ist behoben.
mein Arduino mega hatte irgendwie Schaden genommen. ich benutze jetzt ein UNO.
momentan wäre es mir sehr hilfreich wenn ich Hilfe zu dem Koderpin bekomme der ab und zu auf HIGH geht obwhol der Sensor angesteckt ist

pispa:
momentan wäre es mir sehr hilfreich wenn ich Hilfe zu dem Koderpin bekomme der ab und zu auf HIGH geht obwhol der Sensor angesteckt ist

Ohne Programm, ohne Schaltplan, ohne Foto, wie stellst Du Dir da die Hilfe vor? Eine Glaskugel wurde mir leider nicht zugestanden ::slight_smile: