INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
"Nichtlineare" Zähler
05.06.2016, 11:55
Beitrag #1
"Nichtlineare" Zähler
Hallo zusammen,
habe folgendes Problem. Ich will einen nichtlinearen Zähler programmieren.
Lineare Zähler sind ja recht simpel und funktionieren in meinem Programm auch ohne Probleme.

Ich müsste in dieser Reihenfolge zählen lassen:

58
59
56
57
62
63
60
61
50
51
48
49
54
55
52
53

dann wieder von vorne

Ich hoffe, dass das einigermaßen verständlich war =)



Das waren meine Versuche :
---------------------------------

Beispiel für einen Zähler (+1):
Code:
...
...
int counter1 = 0;  // Zähler1 Startwert = 0
...
...

void setup ()
...
...

void loop ()
counter1 = counter1 + 1;  // Zähler1 permanent + 1

// Funktioniert ohne Probleme

...
...


"Nichtlinearer" Zähler Versuch:
Code:
...
...
int counter2 = 58;  // Zähler2 Startwert = 58
...
...

void setup ()
...
...

void loop ()
counter2 = 59;
counter2 = 56;
counter2 = 57;
counter2 = 62;
counter2 = 63;
counter2 = 60;
counter2 = 61;
counter2 = 50;
counter2 = 51;
counter2 = 48;
counter2 = 49;
counter2 = 54;
counter2 = 55;
counter2 = 52;
counter2 = 53;

// Jetzt müsste der Zähler wieder von vorne anfangen. Also bei 58.

// So ist der Wert für counter2 immer der letzte in der Reihe. Also in dem Fall 53

// Funktioniert so also leider nicht


...
...
...


"Nichtlinearer" Zähler Versuch 2:
Code:
...
...
int counter2 = 58;  // Zähler2 Startwert = 58
...
...

void setup ()
...
...

void loop ()
counter2 = counter2 + 1;  // counter2 wird immer 1 addiert
if (counter2 > 59) {         // wenn counter2 größer 59,
  counter2 = 56;}            // dann counter2 = 56
if (counter2 > 57) {        // wenn counter2 größer 57,
  counter2 = 62;}           // dann counter2 = 62
if (counter2 > 63) {        // usw ...
  counter2 = 60;}
if (counter2 > 61) {
  counter2 = 50;}  
if (counter2 > 51) {
  counter2= 48;}    
if (counter2 > 49) {
  counter2 = 54;}
if (counter2 > 55) {
  counter2 = 52;}
if (counter2 > 53) {
  counter2 = 58;}           // Jetzt ist counter2 wieder 58 und müsste eigentlich wieder oben anfangen, oder ?!?


// Jetzt müsste der Zähler wieder von vorne anfangen. Also bei 58.

// So ist der Wert für counter2 immer der letzte in der Reihe. Also in dem Fall 58

// Funktioniert so also leider auch nicht


...
...
...

Jetzt ist die Frage, ob einer der Versuche funktionieren würde, wenn das "geloopt" werden würde, oder ob das da oben alles Quatsch ist und das irgendwie anders funktioniert Rolleyes

Danke im Voraus

Basti
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
05.06.2016, 12:26 (Dieser Beitrag wurde zuletzt bearbeitet: 05.06.2016 12:27 von rkuehle.)
Beitrag #2
RE: "Nichtlineare" Zähler
Hallo Basti,
auch auf die Gefahr hin, dass ich völlig daneben liege.
Warum packst du die Werte nicht in ein Array?
Im loop() dann eine for - Schleife die die Arraywerte nacheinander an counter2 übergibt.
Nur so eine Idee!?
Grüße Ricardo
Edit: Huch, dass waren dann mal die gleichen Gedanken

Nüchtern betrachtet...ist besoffen besser Big Grin
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
05.06.2016, 12:31
Beitrag #3
RE: "Nichtlineare" Zähler
Hey!

Deine Probleme bei Versuch 2 sind: 1. warum immer ">"? Ein Vergleich auf Gleichheit ist viel sicherer "==".
2. wenn du willst, dass pro Durchlauf sich nur 1 Zahl verändert, immer else if.
Diese Funktion sollte funktionieren, wenn aber gleiche Zahlen öfters in der Reihe vorkommen, eine flag nehmen (noch sicherer). Ein switch-Statement könnte hier auch gut verwendet werden.

Code:
int counter = 58;
int flag = 0;

void count()
{
    if (flag == 0) { counter = 59; flag++; }
    else if (flag == 1) { counter = 56; flag++; }
    //... deine Reihe
    else { counter = 58; flag = 0; }
}

Ansonsten das hier verwenden:

Code:
int counter = 58;

void count()
{
    if (counter == 58) counter = 59;
    else if (counter == 59) counter = 56;
    else if (counter == 56) counter = 57;
    else if (counter == 57) counter = 62;
    else if (counter == 62) counter = 63;
    else if (counter == 63) counter = 60;
    else if (counter == 60) counter = 61;
    else if (counter == 61) counter = 50;
    else if (counter == 50) counter = 51;
    else if (counter == 51) counter = 48;
    else if (counter == 48) counter = 49;
    else if (counter == 49) counter = 54;
    else if (counter == 54) counter = 55;
    else if (counter == 55) counter = 52;
    else if (counter == 52) counter = 53;
    else if (counter == 53) counter = 58;
}
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
05.06.2016, 18:06 (Dieser Beitrag wurde zuletzt bearbeitet: 05.06.2016 19:39 von Turbo-S.)
Beitrag #4
RE: "Nichtlineare" Zähler
Danke schonmal für die Tips Smile

Ich muss dazu sagen, dass ich ein Programmier Noob bin Blush


Habe mal ein bisschen rumgespielt....

Hier ist mal ein kompletter Beispielcode. Und zwar soll das ganze eine CAN-Bus Simulation werden.


Code:
#include <mcp_can.h>
#include <SPI.h>

// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10

const int SPI_CS_PIN = 10;

MCP_CAN CAN(SPI_CS_PIN);                                    // Set CS pin


void setup()
{
    Serial.begin(115200);

    while (CAN_OK != CAN.begin(CAN_500KBPS))              // init can bus : baudrate = 500k
    {
        Serial.println("CAN BUS Shield init fail");
        Serial.println(" Init CAN BUS Shield again");
        delay(100);
    }
    Serial.println("CAN BUS Shield init ok!");
}


int counter1 = 0;
                                                                                                                                                                                                                                                      


void loop()
{
    
    counter1 = counter1 + 1;
    if (counter1 > 255) {
      counter1 = 0;}
    
    int counter[16] = {58, 59, 56, 57, 62, 63, 60, 61, 50, 51, 48, 49, 54, 55, 52, 53};  // Zahlenreihe
    int i;
    for (i = 0; i <= 15; i++) {
    Serial.println (counter[i]);  }  // Zahlenreihe wird im SerialMonitor korrekt angezeigt

  
  
    unsigned char msg1[8] = {counter1, 0, 0, 0, 0, 0, 0, 0};     // Botschaft 1 // Byte1 = counter1 0-255
    CAN.sendMsgBuf(0x100, 0, 8, msg1);  // Botschaft 1 - ID100, Standardframe (11bit ID), DLC 8 Byte, Botschaft msg1

    unsigned char msg2[8] = {counter[i], 0, 0, 0, 0, 0, 0, 0};     // Botschaft 2 // Byte 1 soll die Zahlenreihe anzeigen
    CAN.sendMsgBuf(0x200, 0, 8, msg2);  // Botschaft 2 - ID200, Standardframe (11bit ID), DLC 8 Byte, Botschaft msg2
    
    unsigned char msg3[8] = {0, 0, 0, 0, 0, 0, 0, 0};  // Botschaft 3
    CAN.sendMsgBuf(0x300, 0, 8, msg3);  // Botschaft 3 - ID300, Standardframe (11bit ID), DLC 8 Byte, Botschaft msg3
  
    delay(100);

    // Alle Botschaften werden alle 100ms gesendet
    
}

Im SerialMonitor wird die Zahlenreihe angezeigt. In der CAN-Botschaft allerdings nicht Huh

Weiß jemand, woran das liegen kann ? Confused




Danke

Basti

EDIT : Bild als Attachment


Angehängte Datei(en) Thumbnail(s)
   
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
05.06.2016, 19:40
Beitrag #5
RE: "Nichtlineare" Zähler
(05.06.2016 19:35)Lötzinnerhitzer schrieb:  OT:
bitte erwarte keinen Zuspruch, wenn Du Deine Bilder auf derart verseuchten Seiten ablegst und dorhin verlinkst.

Geändert Blush
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
05.06.2016, 20:38
Beitrag #6
RE: "Nichtlineare" Zähler
Hallo Basti,

ich nehme an, dass die Ausgabe zum CAN-Bus ebenfalls in der for-Schleife gewünscht ist. Dafür steht das "}" der Schleife aber an der falschen Stelle im Programm.

Teste mal diesen Code:
Code:
#include <mcp_can.h>
#include <SPI.h>

// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10

const int SPI_CS_PIN = 10;

MCP_CAN CAN(SPI_CS_PIN);                                    // Set CS pin


void setup()
{
  Serial.begin(115200);

  while (CAN_OK != CAN.begin(CAN_500KBPS))              // init can bus : baudrate = 500k
  {
    Serial.println("CAN BUS Shield init fail");
    Serial.println(" Init CAN BUS Shield again");
    delay(100);
  }
  Serial.println("CAN BUS Shield init ok!");
}


int counter1 = 0;



void loop()
{

  counter1 = counter1 + 1;
  if (counter1 > 255) {
    counter1 = 0;
  }

  int counter[16] = {58, 59, 56, 57, 62, 63, 60, 61, 50, 51, 48, 49, 54, 55, 52, 53};  // Zahlenreihe
  int i;
  for (i = 0; i <= 15; i++) {
    Serial.println (counter[i]);
    // Zahlenreihe wird im SerialMonitor korrekt angezeigt

    unsigned char msg1[8] = {counter1, 0, 0, 0, 0, 0, 0, 0};     // Botschaft 1 // Byte1 = counter1 0-255
    CAN.sendMsgBuf(0x100, 0, 8, msg1);  // Botschaft 1 - ID100, Standardframe (11bit ID), DLC 8 Byte, Botschaft msg1

    unsigned char msg2[8] = {counter[i], 0, 0, 0, 0, 0, 0, 0};     // Botschaft 2 // Byte 1 soll die Zahlenreihe anzeigen
    CAN.sendMsgBuf(0x200, 0, 8, msg2);  // Botschaft 2 - ID200, Standardframe (11bit ID), DLC 8 Byte, Botschaft msg2

    unsigned char msg3[8] = {0, 0, 0, 0, 0, 0, 0, 0};  // Botschaft 3
    CAN.sendMsgBuf(0x300, 0, 8, msg3);  // Botschaft 3 - ID300, Standardframe (11bit ID), DLC 8 Byte, Botschaft msg3
  }
  
  delay(100);

  // Alle Botschaften werden alle 100ms gesendet

}

Gruß
Arne

ExclamationMit zunehmender Anzahl qualifizierter Informationen bei einer Problemstellung, erhöht sich zwangsläufig die Gefahr auf eine zielführende Antwort.Exclamation
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
19.07.2016, 17:34
Beitrag #7
RE: "Nichtlineare" Zähler
Hallo,
sorry, dass ich mich solange nicht gemeldet habe. Hatte wenig Zeit, konnte jetzt aber ein bisschen weiter am Arduino "spielen" Wink

@ardu_arne : Danke für den Tip. Kleine Klammer, große Wirkung Smile

Jetzt kommen noch ein paar Details dazu. Und zwar ist mein Ziel die definierten Zähler / Arrays in unterschiedlichen Zykluszeiten zu senden. Beides unabhängig voneinander bekomme ich zum laufen. Bei unterschiedlichen Zykluszeiten werden einige Botschaften "verschluckt". Kann das sein, dass der Arduino in irgendeiner Form zu langsam für solche Sachen ist ?

Habe hier mal den Code:

Code:
#include <mcp_can.h>
#include <SPI.h>

const int SPI_CS_PIN = 10;

MCP_CAN CAN(SPI_CS_PIN);                                  


// ZYKLUS-ZEITEN
unsigned long previousMillis = 0;
const long interval = 50;                  // 50ms

unsigned long previousMillis1 = 0;
const long interval1 = 100;               // 100ms

unsigned long previousMillis2 = 0;
const long interval2 = 200;               // 200ms



// ZÄHLER

int counter16 = 0;    // Counter + 16
int counter_16 = 240; // Counter - 16



void setup()
{
    Serial.begin(115200);

    while (CAN_OK != CAN.begin(CAN_500KBPS))              
    {
        Serial.println("CAN BUS Shield init fail");
        Serial.println(" Init CAN BUS Shield again");
        delay(100);
    }
    Serial.println("CAN BUS Shield init ok!");

  

}


void loop()
{

// Zähler 1 (0+16)
counter16 = counter16 + 16;
if (counter16 > 240) {        // wenn counter größer 240, dann ...
  counter16 = 0;     }        // counter = 0 (Ausgangsposition)


// Zähler 2 (240-16)
counter_16 = counter_16 - 16;
if (counter_16 < 0) {          // wenn counter kleiner 0, dann ...
  counter_16 = 240;  }          // counter = 240 (Ausgangsposition)


    



  // Array für Botschaftenfolge (counter[i])
  
  int counter[16] = {0x3A, 0x3B, 0x38, 0x39, 0x3E, 0x3F, 0x3C, 0x3D, 0x32, 0x33, 0x30, 0x31, 0x36, 0x37, 0x34, 0x35};  // Botschaftenreihe
  int i;
  for (i = 0; i <= 15; i++) {
{

  
  // Zykluszeit = 50ms

  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
  previousMillis = currentMillis;
    
    // Botschaft 1 mit 2 Zählern
    unsigned char msg1[8] = {counter16, counter_16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    CAN.sendMsgBuf(0x100, 0, 8, msg1);  
    

    }                      
    
}

{

  // Zykluszeit = 100ms
  
  unsigned long currentMillis1 = millis();
  if (currentMillis1 - previousMillis1 >= interval1) {
  previousMillis1 = currentMillis1;
  

    // Botschaft 2 mit Array
    unsigned char msg2[5] = {counter[i], 0xA2, 0x87, 0x5F, 0x80};
    CAN.sendMsgBuf(0x200, 0, 5, msg2);    
  
}

{
  // Zykluszeit = 200ms
  unsigned long currentMillis2 = millis();
  if (currentMillis2 - previousMillis2 >= interval2) {
  previousMillis2 = currentMillis2;


    // Botschaft 3
    unsigned char msg3[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C};
    CAN.sendMsgBuf(0x300, 0, 7, msg3);  

  
}


}  
}
}  
}

Kann man das so machen, oder gibt es hierzu vielleicht eine elegantere Lösung ?

Im Anhang sind einige Screenshots. Wenn ich die Codezeilen für die unterschiedlichen Zykluszeiten weglasse, laufen die Zähler und Arrays ohne Fehler durch. Also wird dort der Hund begraben sein, denk ich mal.

   
   
   

Vielen Danke schonmal

Gruß
Basti
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
19.07.2016, 21:15
Beitrag #8
RE: "Nichtlineare" Zähler
Hallo Basti,

dass der Arduino Botschaften "verschluckt" glaube ich nicht.
Vielleicht ist er einfach nur zu langsam um die gewünschten Zeiten einzuhalten und deshalb kommen die Telegramme auf der Gegenseite verspätet an?

Aber es ist auch so, dass lokale Variablen beim Verlassen der Funktion in der sie deklariert sind ihre Gültigkeit verlieren und beim erneuten Eintritt in die Funktion neu angelegt werden. Das kostet Zeit.
Wenn eine lokale Variable in einer Schleife verwendet wird die 20x durchlaufen wird, dann wird diese Variable u.U. 20x neu angelegt. Das kostet dann 20x Zeit. Bei den Arrays msg1,msg2,msg3 wäre das der Fall.
Das kann man umgehen wenn man diese Variablen global deklariert.

Ich habe das an deinem Code mal versucht zu ändern. Ich kann leider nicht garantieren dass das Programm mit den Änderungen noch funktioniert weil ich nicht testen kann. Wenn der Code aber noch läuft, dann läuft er jetzt schneller als vorher. Aber er braucht auch mehr RAM-Speicher was aber derzeit noch kein Problem ist.
Code:
#include <mcp_can.h>
#include <SPI.h>

const int SPI_CS_PIN = 10;

MCP_CAN CAN(SPI_CS_PIN);


// ZYKLUS-ZEITEN
unsigned long previousMillis = 0;
unsigned long currentMillis  = 0;
const long interval = 50;                  // 50ms

unsigned long previousMillis1 = 0;
unsigned long currentMillis1  = 0;
const long interval1 = 100;               // 100ms

unsigned long previousMillis2 = 0;
unsigned long currentMillis2  = 0;
const long interval2 = 200;               // 200ms

int counter[16] = {0x3A, 0x3B, 0x38, 0x39, 0x3E, 0x3F, 0x3C, 0x3D, 0x32, 0x33, 0x30, 0x31, 0x36, 0x37, 0x34, 0x35};  // Botschaftenreihe
int i;

// ZÄHLER

int counter16 = 0;    // Counter + 16
int counter_16 = 240; // Counter - 16

unsigned char msg1[8] = {counter16, counter_16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char msg2[5] = {counter[i], 0xA2, 0x87, 0x5F, 0x80};
unsigned char msg3[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C};

void setup()
{
  Serial.begin(115200);

  while (CAN_OK != CAN.begin(CAN_500KBPS))
  {
    Serial.println("CAN BUS Shield init fail");
    Serial.println(" Init CAN BUS Shield again");
    delay(100);
  }
  Serial.println("CAN BUS Shield init ok!");
}


void loop()
{
  // Zähler 1 (0+16)
  counter16 += 16;
  if (counter16 > 240) {        // wenn counter größer 240, dann ...
    counter16 = 0;
  }        // counter = 0 (Ausgangsposition)


  // Zähler 2 (240-16)
  counter_16 -= 16;
  if (counter_16 < 0) {          // wenn counter kleiner 0, dann ...
    counter_16 = 240;
  }          // counter = 240 (Ausgangsposition)


  // Array für Botschaftenfolge (counter[i])
  for (i = 0; i <= 15; i++) {

    // Zykluszeit = 50ms
    currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;

      // Botschaft 1 mit 2 Zählern
      CAN.sendMsgBuf(0x100, 0, 8, msg1);
    }


    // Zykluszeit = 100ms
    currentMillis1 = millis();
    if (currentMillis1 - previousMillis1 >= interval1) {
      previousMillis1 = currentMillis1;

      // Botschaft 2 mit Array
      CAN.sendMsgBuf(0x200, 0, 5, msg2);
    }

    {
      // Zykluszeit = 200ms
      currentMillis2 = millis();
      if (currentMillis2 - previousMillis2 >= interval2) {
        previousMillis2 = currentMillis2;

        // Botschaft 3
        CAN.sendMsgBuf(0x300, 0, 7, msg3);
      }
    }
  }
}

Gruß
Arne

ExclamationMit zunehmender Anzahl qualifizierter Informationen bei einer Problemstellung, erhöht sich zwangsläufig die Gefahr auf eine zielführende Antwort.Exclamation
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  Zähler Uwe1475 14 1.442 03.09.2016 20:45
Letzter Beitrag: Uwe1475
  Hardware Zähler MasT3r-A 4 526 24.01.2016 21:33
Letzter Beitrag: ardu_arne
  Array mit Zähler steuern ferdi 20 1.606 19.11.2015 15:11
Letzter Beitrag: ardu_arne
  BCD Zähler 0-9999 peterunterhofer 6 1.350 06.03.2015 12:49
Letzter Beitrag: Foto-Ralf
  Zähler in verschiedenen Modi betreiben Nimes 2 663 25.09.2014 10:19
Letzter Beitrag: Nimes
Bug Zähler von 0 - 1023 mit Rotary Encoder....Wie??? Wampo 1 1.497 15.12.2013 13:48
Letzter Beitrag: Wampo

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste