- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 5 von 6 ErsteErste ... 3456 LetzteLetzte
Ergebnis 41 bis 50 von 54

Thema: Asuro und Barcodes

  1. #41
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    03.07.2007
    Beiträge
    349
    Anzeige

    Powerstation Test
    So, Ziel ist erreicht. Ein Primitivst Regler hält Asuro die paar cm lang einigermaßen in Richtung. Weiters habe ich es jetzt so gemacht dass Asuro nur noch 10cm lang versucht einen Barcode zu finden. Wenn er bis dorthin keinen gefunden hat, bricht er ab.

    Hier der aktualisierte Code:

    Code:
    /*Einstellungen um Asuro fit für die Barcode-Funktion zu machen.*/
    /*Geschwindigkeit links/rechts definieren=>damit Asuro geradeausfährt*/
    #define BC_SPEED 90
    /*Hell/Dunkel Schwelle für Odometrie.
    Linke Odometrie wird als Referenz verwendet*/
    #define BC_OLSCHWELLE 600
    #define BC_ORSCHWELLE 730
    /*Hell/Dunkel Schwelle für Barcode*/
    #define BC_LSCHWELLE 45
    
    
    /*Einstellungen um das Barcode zu ändern.*/
    /*ACHTUNG: Bei Veränderungen von BC_STRICH_ANZAHL müssen in der Funktion
    2 Anpassungen vorgenommen werden! Näheres siehe in der Funktion!*/
    /*Anzahl der Datenbits*/
    #define BC_DATENBITS_ANZAHL 3
    /*Anzahl der Striche(Startbit+Datenbits+Prüfbit inklusive Stoppbit)*/
    #define BC_STRICH_ANZAHL 5
    /*Wie oft pro Strich der Helligkeitswert gemessen werden soll
    ACHTUNG: dafür muss die Strichbreite angepasst werden*/
    #define BC_ABTASTUNGEN_PRO_STRICH 5
    /*Um im bin_erg[] eine 1 auszulösen, müssen pro Strich mindestens
    BC_ABTASTUNGEN_PRO_STRICH-2 Messwerte 1 sein. */
    #define BC_LOGIKSCHWELLE 3
    /*Anzahl der Werte im daten[] Array*/
    #define BC_MAX_WERTE 55
    /*Fehlercodes*/
    #define BC_FEHLER_PARITY 255
    #define BC_FEHLER_RICHTUNG 254
    
    unsigned char fkt_barcode_lesen(void)
    {
        unsigned int ldata[2]={0},odata[2]={0};
        unsigned int led_on[2]={0},led_off[2]={0};
        unsigned int links=0,rechts=0,ges=0;
    
        unsigned char flag_l=0,flag_r=0,n=0,startbit=0,summe=0,index=0,dez_erg=0,richtung=0;
        unsigned char odo_counter=0,counter_l=0,counter_r=0,speed_l=BC_SPEED,speed_r=BC_SPEED;
        unsigned char daten[BC_MAX_WERTE]={0},bin_erg[BC_STRICH_ANZAHL-1]={0};
        MotorDir(FWD,FWD);
        MotorSpeed(BC_SPEED,BC_SPEED);
        StatusLED(OFF);
    
        /*Wegstrecke(odocounter) ab Startbit messen*/
        while(odo_counter<BC_MAX_WERTE)
        {
    
            OdometrieData(odata);
            MotorSpeed(speed_l,speed_r);
    
            /*Bei jedem Tick daten[] Array auffüllen.*/
            if( (flag_l==0 && odata[0]>BC_OLSCHWELLE) ||
                (flag_l==1 && odata[0]<BC_OLSCHWELLE) )
            {
                counter_l++;
                FrontLED(ON);
                LineData(ldata);
                led_on[0]=ldata[0];
                led_on[1]=ldata[1];
    
                FrontLED(OFF);
                LineData(ldata);
                led_off[0]=ldata[0];
                led_off[1]=ldata[1];
    
                links=led_on[0]-led_off[0];
                rechts=led_on[1]-led_off[1];
                ges=(links+rechts)/2;
    
                if(ges<BC_LSCHWELLE)
                {
                    daten[odo_counter]=1;
                    if(startbit==0)
                    {
                        StatusLED(GREEN);
                        startbit=1;
                    }
                }
    
                if(flag_l==0)
                    flag_l=1;
    
                else
                    flag_l=0;
    
    
                if(startbit!=0)
                {
                    odo_counter++;
                }
            }
    
            if( (flag_r==0 && odata[1]>BC_ORSCHWELLE) ||
                (flag_r==1 && odata[1]<BC_ORSCHWELLE) )
            {
                counter_r++;
    
                if(flag_r==0)
                    flag_r=1;
    
                else
                    flag_r=0;
            }
    
            if(Gettime()%75==0 && (counter_l>3 || counter_r>3) )
            {
                if(counter_l<counter_r)
                {
                    speed_l=speed_l+1;
                }
                else if(counter_l>counter_r)
                {
                    speed_l=speed_l-1;
                }
                if( (counter_l>35 || counter_r>35) && startbit==0)
                    break;
            }
    
    
        }
    
        MotorDir(BREAK,BREAK);
        MotorSpeed(0,0);
    
        /*Binärzahl aufbauen + Prüfbit*/
         for(n=0;n<BC_MAX_WERTE;n++)
         {
    
            summe=summe+daten[n];
    
            /*Wenn BC_STRICH_ANZAHL verändert wird,
            muss hier ein entsprechender Eintrag erfolgen*/
            if((n+1)%BC_ABTASTUNGEN_PRO_STRICH==0)
            {
                if((n+1)==(BC_ABTASTUNGEN_PRO_STRICH*3)
                    ||
                    (n+1)==(BC_ABTASTUNGEN_PRO_STRICH*5)
                    ||
                    (n+1)==(BC_ABTASTUNGEN_PRO_STRICH*7)
                    ||
                    (n+1)==(BC_ABTASTUNGEN_PRO_STRICH*9))
                {
                    if(summe>=BC_LOGIKSCHWELLE)
                        bin_erg[index]=1;
                    else
                        bin_erg[index]=0;
    
                    index++;
    
                }
    
            summe=0;
            }
    
         }
    
        /*Richtung erkennen*/
        /*Wenn BC_STRICH_ANZAHL verändert wird,
        muss hier der Faktor angepasst werden.*/
         summe=0;
         for(n=(BC_ABTASTUNGEN_PRO_STRICH*9);n<(BC_ABTASTUNGEN_PRO_STRICH*11);n++)
         {
             summe=summe+daten[n];
         }
         if(summe>=(BC_ABTASTUNGEN_PRO_STRICH*2-BC_LOGIKSCHWELLE))
            richtung=1;
    
    
        /*Binärzahl umwandeln in Dezimalzahl oder Fehlercode zurückgeben*/
    
        /*alles OK => Dezimalzahl zurückgeben*/
        if((bin_erg[0]+bin_erg[1]+bin_erg[2])%2!=bin_erg[3] && richtung==1)
            dez_erg=4*bin_erg[0]+2*bin_erg[1]+1*bin_erg[2];
    
        /*Fehlercode BC_FEHLER_RICHTUNG->falsche Richtung*/
        else if((bin_erg[0]+bin_erg[1]+bin_erg[2])%2!=bin_erg[3] && richtung==0)
            dez_erg=BC_FEHLER_RICHTUNG;
    
        /*Prüfbit falsch*/
        else
            dez_erg=BC_FEHLER_PARITY;
    
    
        StatusLED(OFF);
    
        return dez_erg;
    }
    Beispiel Anwendung der Funktion:
    Code:
    unsigned char fkt_taster(void);
    
    int main(void)
    {
        unsigned char c=0,d=0;
    
        Init();
    
        while(1)
        {
            c=fkt_barcode_lesen();
            SerPrint("\r\nBarcode=");
            PrintInt(c);
    
            if(c!=255 && c!=254)
            {
                for(d=0;d<c;d++)
                {
                    Msleep(500);
                    StatusLED(GREEN);
                    Msleep(500);
                    StatusLED(OFF);
                }
            }
            while(fkt_taster()==0);
        }
    
    
    
    
        return 0;
    }
    
    unsigned char fkt_taster(void)
    {
        unsigned char taster=0;
    
        taster=PollSwitch();
    
        if(taster==PollSwitch() && taster!=0)
            return taster;
        else
            return 0;
    }
    Grüße,
    Harri

  2. #42
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    03.07.2007
    Beiträge
    349
    Und hats schon jemand ausprobiert?
    Wenn ja funktionierts bei Euch?

    Grüße,
    Harri
    Grüße,
    Harri

  3. #43
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Ja, gerade eben ausprobiert.

    Ich musste erst noch eine andere Breite für die Barcode-Striche und -Lücken in EXCEL suchen, und so kann ich erst einmal alle Barcodes zu ca. 80% lesen, die GENAU EIN schwarzes Datenbit haben.
    2 schwarze Datenbits werden eher nur zu 10% gelesen, und alls 3 Bits in schwarz habe ich bis jetzt noch nicht geschafft.

    Versucht habe ich es mit 5 verschiedenen Breiten der Striche. Der erste Druckversuch mit der rein mathematisch berechneten Breite (8-er ODO => 1.5 mm/Tik) hatte eigendlich auch noch am besten funktioniert.

    Alle nicht gelesenen Codes liefern nach einem 'Zufallssystem' die beiden Fehlermeldungen zurück. (Richtung, Prüfbit)

    Trotzdem schon mal nicht schlecht Herr Specht.

    P.S.: Liegt es am Stopcode-Bit?
    Ich habe es wie im oberen Bild gedruckt, da es so aus der EXCEL-Tabelle herraus druckbar ist im Gegensatz zu dem Image, welches du da abgelegt hast. Das Image deutet aber eher ein Stop-Bit an, welches direkt ohne Lücke hinter dem Prüfbit zu malen wäre bei doppelter Breite. (Vielleicht hast du es ja schon beschrieben, aber im Moment finde ich dazu keine Angabe.)
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken barcode-2-1.jpg   barcode-2-2.jpg  
    Lieber Asuro programieren als arbeiten gehen.

  4. #44
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    03.07.2007
    Beiträge
    349
    Wenn du eine 8er ODO hast musst du BC_ABTASTUNGEN_PRO_STRICH von 5 auf 10 setzen. Weiters würde ich mit der BC_LOGIKSCHWELLE etwas raufgehen, so ein Wert um 7 sollte passen.

    Asuro muss über eine weiße Fläche fahren, sobald er den ersten schwarzen Strich erkennt fährt er genau 165mm weit. Das kannst du ja ausmessen und damit vergleichen ob du die Werte richtig eingestellt hast.

    Weiters solltest du darauf achten dass die Barcodes möglichst millimetergenau gedruckt werden.

    Das Stoppbit(in der Breite von 2 Strich) verschmilzt mit dem eventuell vorhandenen Prüfbit(als ein max. 45mm breiter Strich kann entstehen im Extremfall).
    Ich hab mal die Zahlen 4...7 im Anhang angehängt, da sollte man es schön erkennen.
    Wenn du außerdem AutoCAD hast kannst du dir die Barcodes von dort ausdrucken(siehe Anhang), du musst nur das Rechteck um die Barcodes an die druckbare A4 Größe anpassen, und dann beim Plotten dies als "Fenster" wählen. Damit kann man dann auf den mm genau drucken.

    Ich hoffe dass es nun bei dir funktioniert, sonst helf ich natürlich gern weiter(mich interessiert es ja schließlich auch wie "portabel" so ein Asuro Programm denn ist).

    Dieses WE werde ich mal etwas angehen was mich schon seit Ewigkeiten nervt: Eine vernünftige Geradeausfahr-Regelung für Asuro. Ich hab zwar schon einen PI Regler mal gebaut aber diesmal probier ich es auf einen anderen Weg womit man hoffentlich noch bessere Resulate erzielt. Damit man Asuro auch mal perfekt gerade über Strichcodes fahren lassen kann.

    Grüße,
    Harri
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken 4...7.gif  
    Angehängte Dateien Angehängte Dateien
    Grüße,
    Harri

  5. #45
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Hallo harry3,
    den PID-Regler von waste, unter diesem Link kann ich nur empfehlen. waste hat ihn zwar für die Linienverfolgung geschrieben, aber ein kleiner Umbau, und schon kann er auch geradeausfahren.
    Ich habe eine Interrupt-Feste Version davon, soll heißen man kann geradeausfahren 'lassen' und sich dann um seine eigentliche Aufgabe (Barcodes?) kümmern. Interresse?
    Lieber Asuro programieren als arbeiten gehen.

  6. #46
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    03.07.2007
    Beiträge
    349
    Ja zeig mal her den Code für die Interrupt Funktion.

    Ich hab den Regler etwas anders in Planung, aber schaden kann es ja trotzdem nicht andere Ideen zu sehen.

    Grüße,
    Harri
    Grüße,
    Harri

  7. #47
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Hier kommt dann mal die Ersatz-Asuro-LIB von SternThaler.

    Kleine Übersicht:

    --- Timer-Interrupt:
    Sorgt mit dem langen, aber schnellen Code für das 'anschieben' eines weiteren ADC-Wandlers.

    --- main()-Funktion:
    - Starten der gewünschte Wandlergruppe (Hier sinnvoll: ODO)
    - Fahrstrecke vorgeben
    - Loop-Schleife mit zeitgesteuertem Sheduler
    - Alle 2ms den PID-Regler von waste aufrufen

    --- waste-PID-Regler:
    Je nach gewünschtem Regelverhalten ODO- oder LINIEN-Regler nutzen.

    Timer-Interrupt und waste-PID-Regler sind in asuro_st.c/h
    main() natürlich in test.c
    Hinweise:
    - Tik-Anzahl-Vorgabe bei den Tasten bezieht sich auf 8-er Scheiben.
    - Infos zur Tastenbelegung in test.c. (Asuro von vorne ansehen: Taste 1 = links)
    - ODO-Messungen benötigen Anpassungen für die Tik-Ermittlung.
    In der Datei asuro_hw.h sind dafür die Defines HW_RAD_SCHWELLE_LINKS und HW_RAD_SCHWELLE_RECHTS

    @harry3
    Ich möchte nicht, dass du aus meinem Code die Kommentare entfernst, die Funktionsnamen änderst und dann in deinem Link "Meine erstellten Asuro Funktionen..." wieder auftauchen [-X .
    Angehängte Dateien Angehängte Dateien
    Lieber Asuro programieren als arbeiten gehen.

  8. #48
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    03.07.2007
    Beiträge
    349
    Danke ich werds mir anschauen.
    Hab aber inzwischen bereits eine gute Lösung hinbekommen mit Hilfe eines einfachen P Reglers(der I Anteil steckt eh schon in der gemessenen Wegstrecke drinnen).

    Zitat Zitat von Sternthaler
    @harry3
    Ich möchte nicht, dass du aus meinem Code die Kommentare entfernst, die Funktionsnamen änderst und dann in deinem Link "Meine erstellten Asuro Funktionen..." wieder auftauchen [-X .
    Wenn ich Codeteile von anderen verwendet habe habe ich diese immer namentlich erwähnt(und das ist im konkreten Fall nur der PID Linienfolger von waste). Die von mir ins Internet gestellte Headerdatei wird jetzt aber sowieso verschwinden weil ich meine ganzen Funktionen nun in eine Menge Einzeldateien geteilt habe um Speicherplatz zu sparen und um etwas mehr Übersicht in die Sache zu bringen.

    Hier nun der aktuelle Code zum Barcodelesen mitsamt des Reglers:

    hs_barcode.h
    Grüße,
    Harri

  9. #49
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Hallo harry3,
    ich habe gerade in deine hs_barcode.h geschaut. (Warum eigendlich immer *.h?)
    Ist auch eine schöne Lösung für die 'parallel' zu erledigenden Arbeiten. Da wirst du dich bestimmt wundern, wie kompliziert ich es gemacht habe.

    Im Kommentar deiner Datei schreibst du folgendes:
    WICHTIG: Die Funktion wurde für die 8er Odometriescheibe ausgelegt(1 Tick=3mm).
    Kann es sein, dass du die 6-er Scheiben meinst?
    Bei meinen 8-er-Scheiben fahre ich nämlich 1,5 mm / Tik.
    Aber warum sollte man dann bei einer 6-er-Scheibe auf 3 mm / Tik kommen?
    Das Verhältnis 8 zu 6 entspricht ja nicht 3 zu 1,5. Gibt es beim Asuro eventuell noch andere Getriebeuntersetzungen / Raddurchmesser?
    Meine beiden Zahnräder haben laut Anleitung jeweils eine Untersetzung von 50 zu 10. Der Raddurchmesser beträgt ca. 38.1 mm
    Rad-Umfang also 119,7 mm
    Umfang / eine Getriebestufe = 119,7 / 5 = 23,94 mm
    Das durch 8 * 2 SW- bzw. WS-Wechsel = 23,94 / 16 = 1,496 also ca. 1,5 mm / Tik. (bei meinem Asuro)

    P.S.: Mit der Anleitung, dass das Stop-Bit eine doppelte Breite hat, ist die Trefferquote bei mir auch eine 'Ecke' besser geworden.
    Lieber Asuro programieren als arbeiten gehen.

  10. #50
    Moderator Robotik Einstein Avatar von damaltor
    Registriert seit
    28.09.2006
    Ort
    Milda
    Alter
    38
    Beiträge
    4.066
    wenn man es genau betrachtet, hat die andere scheibe auch nicht 6 flächen, sondern 12 8schwarz und weiss).
    raddurchmesser: ~38 mm
    umfang: ~120 mm
    nach getriebestufe: ~24 mm
    durch ticks: ~2 mm.

    gute frage woher dann die 3 mm kommen... wer hat das nur ausgerechnet...
    Read... or die.
    ff.mud.de:7600
    Bild hier  

Seite 5 von 6 ErsteErste ... 3456 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests