Go Down

Topic: Fahrrad Blinker,433Mhz, Interrupts... (Read 900 times) previous topic - next topic

gregorss

... eigentlich müsste ich doch ...
Ich habe den Thread nur sehr oberflächlich quergelesen.

Nach allem, was ich dabei aufgeschnappt habe, fällt mir dazu nur ein, Dich (wahrscheinlich wie schon andere) auf den „endlichen Automaten" aufmerksam zu machen. Wirklich sehr gut ist in diesem Zusammenhang die „Nachtwächter-Erklärung". Auch mir ist dazu ein bisschen was eingefallen. Vielleicht ist das ja hilfreich.

Gruß

Gregor
Bei Vollmond ist Neuerde.

FaRmeZZ

#16
Jan 04, 2019, 05:01 pm Last Edit: Jan 04, 2019, 05:07 pm by uwefed Reason: add CODE TAGs </>
Hallo,
danke für deine Hilfe, damit hab ichs hinbekommen :)

So sieht mein Code jetzt aus und funktioniert auch:
Code: [Select]
void loop() {

if(mySwitch.getReceivedValue() == 2210){
 const int firstLED = 5;
 const int lastLED = 13;
 unsigned long currentMillis = millis();
 if (currentMillis - previousMillis >= interval){
   previousMillis = currentMillis;
   LEDON ++;
   LEDOFF = LEDON - 2;
   pixels.setPixelColor(LEDON, pixels.Color(255,255,0));
   pixels.setPixelColor(LEDOFF, pixels.Color(0,0,0));
   pixels.show();
 }
 if (LEDON > lastLED){
   LEDON = firstLED;
 }  
}

if(mySwitch.getReceivedValue() == 1998){
 const int firstLED1 = 6;
 const int lastLED1 = -2;
 unsigned long currentMillis1 = millis();
 if (currentMillis1 - previousMillis1 >= interval){
   previousMillis1 = currentMillis1;
   LEDON1 --;
   LEDOFF1 = LEDON1 + 2;
   pixels.setPixelColor(LEDON1, pixels.Color(255,255,0));
   pixels.setPixelColor(LEDOFF1, pixels.Color(0,0,0));
   pixels.show();
 }
 if (LEDON1 < lastLED1){
   LEDON1 = firstLED1;
 }  
}
}



wenn die Fernbedienung "2210" sendet wird die Binker Links animation abgespielt und die rechte bei "1998" und es kann auch zwischen den beiden animationen "gewechselt werden"

Jetzt habe ich nurnoch ein Problem, aktuell läuft die jeweilige animation nach betätigen des Tasters unendlich oft oder bis der andere Taster gedrückt wird und dann läuft die andere animation unendlich oft.

Ich hätte aber gerne das nach einmaligen betätigen des Tasters die Animation 5 mal durchlaufen wird und dann alle LEDs ausgehen bis wieder ein Taster gedrückt wird.

Wie bekomme ich das hin?

Vielen Dank und Gruß
Patrick

postmaster-ino

Hi
Code: [Select]
if (LEDON > lastLED){
   LEDON = firstLED;
 }

Dort zählst Du mit.
Wenn Du bis 5 gezählt hast, brichst Du das Blinken ab.
Denke, Du musst dann mySwitch.getReceivedValue() leeren.
Bzw. 'die ganze Zeit abfragen' und den Zähler wieder auf Null zurück setzen - solange der Knopf gedrückt ist, soll der Blinker doch wohl blinken, oder?
Dann musst DU Dir aber 'merken', daß Du gerade 'links' oder 'rechts' am Blinken bist, wenn die Variable beim Einlesen selber geleert wird, wenn kein neuer Funk empfangen wird.
Ist aber ebenfalls eine 'ganz normale' State-Maschine.

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

beeblebrox

Immer wieder mein gleicher Tip :

Erst C und/oder C++ auf dem PC lernen (Kommandozeile) und sich selber erst
dann auf die Microcontrollerwelt loslassen.
Sonst hat man einfach zu viele Probleme auf einmal.

Ulli

gregorss

Ich hätte aber gerne ...
Der Tipp von Postmaster-ino ist schon mal ganz gut. Ich würde aber eher einen zusätzlichen „Modus" einbauen, nämlich „Blinker aus". Dann funktioniert der Blinker „wie in echt". Wer weiß, vielleicht macht das das Sternchen an der Eins aus :-)

Gruß

Gregor
Bei Vollmond ist Neuerde.

postmaster-ino

Hi

Nunja - würde den Modus dann nicht AUS nennen wollen - finde am Auto den 'Autobahn-Blinker' (kA, wie Der auf Deutsch heißt, nur Antippen, Blinker blinkt 3x) ganz nett und würde sich hier auch einbauen lassen.
Vom Blinker-Hebel kommt 'Blinker Links', 'Blinker Mitte', 'Blinker Rechts'.
Den Rest machst Du am Empfänger.
Wenn 'Blinker Mitte' den aktuellen Blink-Impuls 'noch fertig blinken' und dann abschalten (oder bis auf mindestens 3 Blink-Zyklen blinken ... und dann NACH dem Blink-Impuls abschalten).

Wenn der Hebel meldet, daß der Blinker betätigt ist, eben in die entsprechende Richtung blinken - hier, beim Wechsel der Richtungen, aber dann nicht erst 'fertig Blinken', da man wohl doch in die andere Richtung will.

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

FaRmeZZ

#21
Jan 05, 2019, 09:33 pm Last Edit: Jan 06, 2019, 01:13 am by uwefed Reason: add CODE TAGs </>
Hallo und danke für eure Ideen,

Der Code sieht jetzt mittlerweile so aus:
Code: [Select]
void loop() {

if(mySwitch.getReceivedValue() == 2210){
funk = 2210;
}
if(mySwitch.getReceivedValue() == 1998){
funk = 1998;
}

if(funk == 2210){
const int firstLED = 5;
const int lastLED = 13;
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval){
previousMillis = currentMillis;
LEDON ++;
LEDOFF = LEDON - 2;
pixels.setPixelColor(LEDON, pixels.Color(255,255,0));
pixels.setPixelColor(LEDOFF, pixels.Color(0,0,0));
pixels.setPixelColor(0, pixels.Color(0,0,0));
pixels.setPixelColor(1, pixels.Color(0,0,0));
pixels.setPixelColor(2, pixels.Color(0,0,0));
pixels.setPixelColor(3, pixels.Color(0,0,0));
pixels.setPixelColor(4, pixels.Color(0,0,0));
pixels.setPixelColor(5, pixels.Color(0,0,0));
pixels.show();
}
if (LEDON > lastLED){
LEDON = firstLED;
count1++;
}  
}
if(count1 >=5){
funk = 0;
count1 = 0;
}
if(funk == 1998){
const int firstLED1 = 6;
const int lastLED1 = -2;
unsigned long currentMillis1 = millis();
if (currentMillis1 - previousMillis1 >= interval){
previousMillis1 = currentMillis1;
LEDON1 --;
LEDOFF1 = LEDON1 + 2;
pixels.setPixelColor(LEDON1, pixels.Color(255,255,0));
pixels.setPixelColor(LEDOFF1, pixels.Color(0,0,0));
pixels.setPixelColor(6, pixels.Color(0,0,0));
pixels.setPixelColor(7, pixels.Color(0,0,0));
pixels.setPixelColor(8, pixels.Color(0,0,0));
pixels.setPixelColor(9, pixels.Color(0,0,0));
pixels.setPixelColor(10, pixels.Color(0,0,0));
pixels.setPixelColor(11, pixels.Color(0,0,0));
pixels.show();
}
if (LEDON1 < lastLED1){
LEDON1 = firstLED1;
count2++;
}  
}
if(count2 >=5){
funk = 0;
count2 = 0;
}
}

und funktioniert ansich auch wie gewollt, beim einmaligen betätigen eines Tasters wird die jeweilige Animation 5x ausgeführt und wenn man den anderen Taster währenddessen drückt wird die aktuelle animation abgebrochen und die andere ausgeführt.

gibt nurnoch eine Sache die mich ein wenig stört, undzwar:

Ich blinke Links, also fängt er von der Mitte an nach aussen die Leds Nr 6 bis 11 an und wieder auszumachen. Wenn ich jetzt den Taster für Rechts Blinken drücke stopt er die Linke Animation und startet die Rechte. Wenn er diese aber zb. in dem moment stopt während die Animation gerade zb. bei LED8 war, ist die LED 8 der neue startpunkt falls man wieder den Taster für Links Blinken betätigt.

Ich hoffe ich habs geschafft das einigermasen verständlich zu erklären... habe mal noch ein Bild der Platine mit den LEDs gemacht und diese beschriftet...

Was ich schon probiert habe ist das jeweillige LEDON und LEDOFF wieder auf den richtigen "startwert" zu setzen sobald der jeweils andere Blinkertaster gedrückt wird aber das hatte zur folge das wenn man den Taster gedrückt hällt er denn wert dauerhaft zurücksetzt was nicht sein darf...

Vielleicht hat ja jemand von euch eine Idee :)
Gruß
Patrick

HotSystems

Den Sketch kann doch keiner lesen.
Warum verwendest du keine Code-Tags ?
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

ardubu

versuch es mal so
Code: [Select]
void loop() {

if(mySwitch.getReceivedValue() == 2210){
funk = 2210;
}
if(mySwitch.getReceivedValue() == 1998){
funk = 1998;
}

if(funk == 2210){
const int firstLED = 5;
const int lastLED = 13;
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval){
previousMillis = currentMillis;
LEDON ++;
LEDOFF = LEDON - 2;
pixels.setPixelColor(LEDON, pixels.Color(255,255,0));
pixels.setPixelColor(LEDOFF, pixels.Color(0,0,0));
for (int x=0;x<6;x++)
pixels.setPixelColor(x, pixels.Color(0,0,0));

pixels.show();
}
if (LEDON > lastLED){
LEDON = firstLED;
count1++;

}
if(count1 >=5){
funk = 0;
count1 = 0;
LEDON = 0;
LEDON1 = 0;
}
if(funk == 1998){
const int firstLED1 = 6;
const int lastLED1 = -2;
unsigned long currentMillis1 = millis();
if (currentMillis1 - previousMillis1 >= interval){
previousMillis1 = currentMillis1;
LEDON1 --;
LEDOFF1 = LEDON1 + 2;
pixels.setPixelColor(LEDON1, pixels.Color(255,255,0));
pixels.setPixelColor(LEDOFF1, pixels.Color(0,0,0));
for (int x=6;x<12;x++)
pixels.setPixelColor(x, pixels.Color(0,0,0));

pixels.show();
}
if (LEDON1 < lastLED1){
LEDON1 = firstLED1;
count2++;

}
if(count2 >=5){
funk = 0;
count2 = 0;
LEDON = 0;
LEDON1 = 0;
}
}

gregorss

... finde am Auto den 'Autobahn-Blinker' (kA, wie Der auf Deutsch heißt, nur Antippen, Blinker blinkt 3x) ganz nett und würde sich hier auch einbauen lassen. ...
Hihi ... dann wären es im Ganzen also 5 Blink-Modi:

- endlos rechts blinken
- 3 x rechts blinken
- aus
- 3 x links blinken
- endlos links blinken

Plus Warnblinkschalter ...

Mit der richtigen „Programmierstrategie" kann man da noch viel anstellen :-) Wie fast immer wird das nur von der Fantasie begrenzt. Man könnte auch invers blinken (aus-an-aus-... statt an-aus-an-...) *g*

Gruß

Gregor
Bei Vollmond ist Neuerde.

postmaster-ino

(und da man programmierbare RGB-LEDs nimmt, auch mit Blau/Rot/was_weiß_ich-Blitz-Licht ... damit die Fahrbahn auch frei ist, wenn man Da an kommt)
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

FaRmeZZ

(und da man programmierbare RGB-LEDs nimmt, auch mit Blau/Rot/was_weiß_ich-Blitz-Licht ... damit die Fahrbahn auch frei ist, wenn man Da an kommt)
Ja genau deswegen habe ich mich für die addresierbare RGB Variante entschieden, gibt so viele Möglichkeiten die man damit noch machen kann wie zb KIT

FaRmeZZ

Hallo, ich nochmal :P

Bin gerade dabei den G-Sensor zu testen.
Ich frage die Raw Daten der 3 Achsen über lis.read(); aus.
Er gibt mir dann die Raw data der 3 Achsen.

Anhand der Z Achse soll das bremslicht angehen, sprich wenn Z Achse über eine bestimmte negativ Beschleunigung geht, sollen die LEDs rot werden.

Habe ich soweit auch hinbekommen, aber wenn man den Sensor bzw die Platine um ihre eigene Achse dreht, lösen die LEDs auch aus weil man die Z Achse dann ja sozusagen in die Erdanziehungskraft dreht und diese dann sich auf die Z Achse auswirkt.

Das muss ich aber unbedingt verhindern, bin am verzweifeln.... sonst würde ja das Bremslicht angehen wenn man den berg hoch oder runter fährt...

Also ich muss irgendwie die Beschleunigung von der Z Achse ausrechnen ohne die Erdanziehungskraft zu berücksichtigen.... damit die LEDs nur rot werden wenn das Fahrrad wirklich langsamer wird...

Hoffe jemand von euch kann mir da helfen..

Gruß
Patrick

michael_x

#28
Jan 18, 2019, 11:09 pm Last Edit: Jan 18, 2019, 11:10 pm by michael_x
Neben der resultierenden Richtung der Beschleunigung interessiert dich auch der Gesamtbetrag. Der sollte 1g bleiben, wenn du mit konstanter Geschwindigkeit bergab fährst, und sogar <1g wenn du es steil abwärts laufen lässt. 
Beim Bremsen, Beschleunigen und bei Kurvenfahrt hast du >1g
Aber ob du so stabile Werte messen kannst, dass du mit einer Bremslicht-Funktion zufrieden bist, bleibt für mich sehr fraglich.
Nicht ohne Grund zeigen normale Bremslichter eher den Druck in der Bremsleitung an.

FaRmeZZ

Hallo,

Bin jetzt sogut wie fertig mit dem Blinker, habe lediglich nurnoch ein Problem.

#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();

#include <Adafruit_NeoPixel.h>
#define NUMPIXELS 12                                              //12 LEDs sind verbaut
#define LED_PIN 6                                                //LEDs sind an Pin 6 angeschlossen
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, LED_PIN, NEO_GRB + NEO_KHZ800); //konfigurieren der LEDs

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_LIS3DH.h>
#include <Adafruit_Sensor.h>
Adafruit_LIS3DH lis = Adafruit_LIS3DH();                          //dem G-Sensor den namen "lis" geben
int lisZ;

int LEDONL1 = 6;
int LEDONL2 = 5;
int LEDONR1 = 5;
int LEDONR2 = 6;
unsigned long previousMillis = 0;
unsigned long previousMillis1 = 0;
const long interval = 130;
int count1 = 0;
int count2 = 0;

enum State : int
{
  AUS, LINKS_BLINKEN, RECHTS_BLINKEN
};
enum State BlinkerState;

void setup() {
  Serial.begin(9600);
  lis.begin(0x19);                                              //I²C Addresse des G-Sensors einstellen
  lis.setRange(LIS3DH_RANGE_16_G);                              // Range vom G-Sensor einstellen,   2, 4, 8 or 16 G!
  mySwitch.enableReceive(1);                                    //433Mhz Empfänger an Interrupt Pin1 initialisieren
  pinMode(5, OUTPUT);                                           //an Pin5 ist der P-Kanal Mosfet der die LEDs ein und ausschalten kann
  digitalWrite(5, LOW);                                         //LEDs einschalten
  pixels.begin();                                               //LEDs initialiesieren
}


void loop() {
  sensors_event_t event;                                        //LIS3DH abfragen
  lis.getEvent(&event);
  if (mySwitch.getReceivedValue() == 2210) BlinkerState = LINKS_BLINKEN;
  if (mySwitch.getReceivedValue() == 1998) BlinkerState = RECHTS_BLINKEN;

  if (BlinkerState == AUS && event.acceleration.z <= -5) {
    pixels.setPixelColor(0, pixels.Color(255, 0, 0));
    pixels.setPixelColor(1, pixels.Color(255, 0, 0));
    pixels.setPixelColor(2, pixels.Color(255, 0, 0));
    pixels.setPixelColor(3, pixels.Color(255, 0, 0));
    pixels.setPixelColor(4, pixels.Color(255, 0, 0));
    pixels.setPixelColor(5, pixels.Color(255, 0, 0));
    pixels.setPixelColor(6, pixels.Color(255, 0, 0));
    pixels.setPixelColor(7, pixels.Color(255, 0, 0));
    pixels.setPixelColor(8, pixels.Color(255, 0, 0));
    pixels.setPixelColor(9, pixels.Color(255, 0, 0));
    pixels.setPixelColor(10, pixels.Color(255, 0, 0));
    pixels.setPixelColor(11, pixels.Color(255, 0, 0));
    pixels.show();
  }

  if (BlinkerState == AUS && event.acceleration.z >= -5) {
    pixels.clear();
    pixels.show();
  }

  if (BlinkerState == LINKS_BLINKEN) {
    count2 = 0;                                                 //Wiederholungszähler von der rechten Blinker Animation auf 0 setzen
    const int firstLEDL1 = 5;                                   //erste Start LED der Animation festlegen
    const int firstLEDL2 = 4;                                   //zweite Start LED der Animation festlegen
    const int lastLED = 13;                                     //letzte LED der Animation festlegen
    unsigned long currentMillis = millis();                     //in "currentMillis" die aktuelle systemzeit speichern
    if (currentMillis - previousMillis >= interval) {           //workaround um ein blinkintervall von 130ms zu erzeugen ohne delay()
      previousMillis = currentMillis;                           //die IF-Schleife wird alle 130ms (siehe int intervall = 130;) wiederholt
      LEDONL1 ++;                                               //nächste LED anschalten
      LEDONL2 ++;                                               //übernächste LED anschalten
      if (event.acceleration.z <= -5) {
        pixels.setPixelColor(0, pixels.Color(255, 0, 0));
        pixels.setPixelColor(1, pixels.Color(255, 0, 0));
        pixels.setPixelColor(2, pixels.Color(255, 0, 0));
        pixels.setPixelColor(3, pixels.Color(255, 0, 0));
        pixels.setPixelColor(4, pixels.Color(255, 0, 0));
        pixels.setPixelColor(5, pixels.Color(255, 0, 0));
        pixels.setPixelColor(6, pixels.Color(255, 0, 0));
        pixels.setPixelColor(7, pixels.Color(255, 0, 0));
        pixels.setPixelColor(8, pixels.Color(255, 0, 0));
        pixels.setPixelColor(9, pixels.Color(255, 0, 0));
        pixels.setPixelColor(10, pixels.Color(255, 0, 0));
        pixels.setPixelColor(11, pixels.Color(255, 0, 0));
      } else {                                                  // wenn Variable "lisZ" gleich 0, alle LEDs aus
        pixels.clear();
      }
      pixels.setPixelColor(LEDONL1, pixels.Color(255, 80, 0));  //LED die in Variable "LEDONL1" steht einschalten
      pixels.setPixelColor(LEDONL2, pixels.Color(255, 80, 0));  //LED die in Variable "LEDONL2" steht einschalten
      pixels.show();                                            //Alle LEDs aktualiesieren
      if (LEDONL1 > lastLED) {                                  //wenn LEDONL1 den wer der konstanten Variable "lastLED" erreicht hat
        LEDONL1 = firstLEDL1;                                   //startwert der ersten LED wieder auf Anfang setzen
        LEDONL2 = firstLEDL2;                                   //startwert der zweiten LED wieder auf Anfang setzen
        count1++;                                               // "count1! +1, die Variable is zum Mitzählen wie oft die Animation durchgeführt wurde
      }
      if (count1 >= 5) {                                        // wenn "count1" größer/gleich 5 dann:
        BlinkerState = AUS;                                     // variable "funk" auf 0 setzen sprich animation stoppen
        count1 = 0;                                             // variable "funk" zurück auf 0 setzen, damit im nächsten durchlauf wieder bis 5 gezählt werden kann
      }
    }
  }
  if (BlinkerState == RECHTS_BLINKEN) {
    count1 = 0;
    const int firstLEDR1 = 6;
    const int firstLEDR2 = 7;
    const int lastLED1 = -2;
    unsigned long currentMillis1 = millis();
    if (currentMillis1 - previousMillis1 >= interval) {
      previousMillis1 = currentMillis1;
      LEDONR1 --;
      LEDONR2 --;
      if (event.acceleration.z <= -5) {
        pixels.setPixelColor(0, pixels.Color(255, 0, 0));
        pixels.setPixelColor(1, pixels.Color(255, 0, 0));
        pixels.setPixelColor(2, pixels.Color(255, 0, 0));
        pixels.setPixelColor(3, pixels.Color(255, 0, 0));
        pixels.setPixelColor(4, pixels.Color(255, 0, 0));
        pixels.setPixelColor(5, pixels.Color(255, 0, 0));
        pixels.setPixelColor(6, pixels.Color(255, 0, 0));
        pixels.setPixelColor(7, pixels.Color(255, 0, 0));
        pixels.setPixelColor(8, pixels.Color(255, 0, 0));
        pixels.setPixelColor(9, pixels.Color(255, 0, 0));
        pixels.setPixelColor(10, pixels.Color(255, 0, 0));
        pixels.setPixelColor(11, pixels.Color(255, 0, 0));
      } else {
        pixels.clear();
      }
      pixels.setPixelColor(LEDONR1, pixels.Color(255, 80, 0));
      pixels.setPixelColor(LEDONR2, pixels.Color(255, 80, 0));
      pixels.show();

      if (LEDONR1 < lastLED1) {
        LEDONR1 = firstLEDR1;
        LEDONR2 = firstLEDR2;
        count2++;
      }
      if (count2 >= 5) {
        BlinkerState = AUS;
        count2 = 0;
      }
    }
  }
}


Ich habe 4 if schleifen, je eine wo die Blink animation drine is (links oder rechts), eine schleife wo alle LEDs aus sein sollen und die schleife wo alle LEDs rot sein sollen als Bremslicht.

funktioniert auch alles wie es soll, solange ich die schleife wo alle LEDs aus sein sollen ausklammer, sobald ich die wieder aktiviere funktioniert nur das Bremslich, keine Blinkeranimation.
Ich habe mir dann mal über SerialMonitor die Werte angeschaut die das 433Mhz Empfänger Modul ausgibt, immer 0 egal welche Taste ich an der Fernbedienung drücke....also kann BlinkerState natürlich nicht auf LINKS_BLINKEN oder RECHTS_BLINKEN wechseln.....

Woran kann das liegen? es hängt irgendwie mit dem pixels.show() in der Zeile 67 zusammen....
aber was sollte das für ein einfluss auf den Funkempfänger haben?

Bin am verzweifeln.....

Gruß
Patrick

Go Up