- LiFePO4 Speicher Test         
Ergebnis 1 bis 10 von 13

Thema: TIME funktioniert nicht beim ATtiny44, wie kann ich das Problem lösen?

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    12.02.2025
    Beiträge
    7

    TIME funktioniert nicht beim ATtiny44, wie kann ich das Problem lösen?

    Hi,

    habe mit einem 4 Zeilen Display und einem ATtiny44 einen einfachen Lichtschranken Rundenzähler für Schlitzrennbahnen gebastelt, hat alles gut funktioniert bis ich einen Zeitzähler brauchte der die Durchfahrt eines Slotcar korrekt erkennt und nur eine Runde zählt. Na ja, es funktioniert ( do : waitms 50 : until Spur_1 = 0 ) mit dem Nachteil das während den 50 ms die Spur 2 nicht erfasst wird wenn die Slotcars gleichzeitig durch die Lichtschranke fahren. Am PC war das kein Problem da bei Gambas man einfach mit ( Signal = Time : If Signal + 100 < time then : durchfahrt = 1 : endif ), und so etwas schaffe ich nicht mit Bascom.

    Das ganze Programm:
    Code:
    ' Compiler: Bascom-Demo 2.0.7.5
    
    ' Dateiname:	Formel X.avr
    ' Funktion:	ein Rundenzähler für Schlitzautos mit einem ATtiny44 auf einem 20x4 Display
    ' Datum:	Start 01.02.2025, Stand 12.02.2025
    ' Von:		Naubaddi foto-schubser@arcor.de
    '
    ' ATtiny44 (B.3 RESET)
    '
    '                                    +----v----+
    '                                VCC | 1     14| GND
    '                   PCINT8/XTAL1 B.0 | 2     13| A.0 ADC0/AREF/PCINT0
    '                   PCINT9/XTAL2 B.1 | 3     12| A.1 ADC1/AIN0/PCINT1
    '               PCINT11/RESET/dW B.3 | 4     11| A.2 ADC2/AIN1/PCINT2
    '        PCINT10/INT0/OC0A/CKOUT B.2 | 5     10| A.3 ADC3/T0/PCINT3
    '           PCINT7/ICP/OC0B/ADC7 A.7 | 6      9| A.4 ADC4/USCK/SCL/T1/PCINT4
    '      PCINT6/OC1A/SDA/MOSI/ADC6 A.6 | 7      8| A.5 ADC5/DO/MISO/OC1B/PCINT5
    '                                    +---------+
    '
    
    ' --- Mikrocontroler Daten... ----------------------------------------------------------------------------------
    
    $regfile   = "attiny44.dat"
    $crystal   = 8000000
    $hwstack   = 40
    $swstack   = 40
    $framesize = 40
    
    ' --- Deklarationen... -----------------------------------------------------------------------------------------
    
    enable interrupts
    config timer0 = timer , prescale = 256
    on timer0 Timer_0
    disable timer0
    
    config porta  = output
    config portb  = input
    
    config lcdpin = pin , Db4 = porta.2 , Db5 = porta.3 , Db6 = porta.4 , Db7 = porta.5 , E = porta.0 , Rs = porta.1
    config lcd    = 20 * 4
    cursor off    : cls
    
    Ampel_1     alias porta.6      : Ampel_1      =   0	' Spannung für die Ampel Spur 1
    Ampel_2     alias porta.7      : Ampel_2      =   0	' Spannung für die Ampel Spur 2
    Spur_1      alias  pinb.1				' Spur 1 und Auswahl -
    Spur_2      alias  pinb.2				' Spur 2 und Auswahl +
    Start_Stopp alias  pinb.0				' das Rennen starten/stoppen
    
    ' --- Variablen... ---------------------------------------------------------------------------------------------
    
    dim Soll         as byte       : Soll         = 122	' 122,07 ist ca. eine Sekunde
    dim Ist          as byte       : Ist          =   1	' Zeit-Zähler bis Ist > Soll erreicht wurde
    dim blinken      as byte       : blinken      =   0	' blinken für die Runden, die Ampel, den Fehlstart...
    
    dim Runden       as byte       : Runden       =  20	' die Anzahl der Runden für ein Rennen
    dim Runde_Spur_1 as byte       : Runde_Spur_1 =   0	' die gefahrenen Runden auf Spur 1
    dim Runde_Spur_2 as byte       : Runde_Spur_2 =   0	' die gefahrenen Runden auf Spur 2
    dim Ampel        as byte       : Ampel        =   0	' die Startampel für Spur 1 und/oder Spur 2
    dim Ampel_Z      as byte       : Ampel_Z      =   0	' ein Zähler für das Blinken der Ampel
    dim Fehlstart    as byte       : Fehlstart    =   0	' ein Fahrer ist vor dem Startsignal losgefahren
    dim rennen       as byte       : rennen       =   0	' läuft das Rennen? 0 = nein, 1 = ja
    dim Z_formatiert as string * 2 : Z_formatiert =  ""	' Zahlen rechtsbündige formatieren
    
    ' --- Programm Anfang ------------------------------------------------------------------------------------------
    
    Z_formatiert = str(Runden)
    locate 1,1 : lcd "Formel X  " ; format(Z_formatiert , "   ") ; " Runden"
    locate 2,1 : lcd "--------------------"
    locate 3,1 : lcd "Spur 1 ---- Runde  0"
    locate 4,1 : lcd "Spur 2 ---- Runde  0"
    
    do
      gosub Runden_einstellen
      if rennen = 1 then
        Z_formatiert = str(Runden)
        locate 1,12 : lcd ; format(Z_formatiert , "  ") ; " Runden"
        locate 2,1  : lcd "--------------------"
        locate 3,1  : lcd "Spur 1 ---- Runde  0"
        locate 4,1  : lcd "Spur 2 ---- Runde  0"
        Runde_Spur_1 = 0 : Runde_Spur_2 = 0
        Ampel = 0 : Ampel_1 = 0 : Ampel_2 = 0
        gosub Ampelphase
        if rennen = 1 then
          do
            if Spur_1 = 1 then
              incr Runde_Spur_1
              Z_formatiert = str(Runde_Spur_1)
              locate 3,19 : lcd ; format(Z_formatiert , "  ")
              do : waitms 55 : loop until Spur_1 = 0
            end if
            if Spur_2 = 1 then
              incr Runde_Spur_2
              Z_formatiert = str(Runde_Spur_2)
              locate 4,19 : lcd ; format(Z_formatiert , "  ")
              do : waitms 55 : loop until Spur_2 = 0
            end if
            if Runde_Spur_1 > Runden then
              rennen = 0 : Ampel_1 = 1
              locate 2,1 : lcd "- * ----------------"
              locate 3,1 : lcd "Spur 1 hat gewonnen "
            end if
            if Runde_Spur_2 > Runden then
              rennen = 0 : Ampel_2 = 1
              locate 2,1 : lcd "---------------- * -"
              locate 4,1 : lcd "Spur 2 hat gewonnen "
            end if
            if rennen = 0 then
              do : waitms 55 : loop until Start_Stopp = 1
              do : waitms 55 : loop until Start_Stopp = 0
              locate 2,1 : lcd "--------------------"
            else
              gosub Abbruch
            endif
          loop until rennen = 0
        end if
      end if
    loop
    
    ' --- Prozeduren, Funktionen... --------------------------------------------------------------------------------
    
    Runden_einstellen:
      Ampel_Z = 0 : blinken =   0
      Ist     = 1 : Soll    = 122
      enable timer0
      do
        if blinken = 1 then
          locate 1,15 : lcd "      "
        else
          locate 1,15 : lcd "Runden"
        end if
        if Spur_1 = 1 then
          decr Runden
          if Runden <  2 then : Runden = 99 : end if
          Z_formatiert = str(Runden)
          locate 1,12 : lcd ; format(Z_formatiert , "  ") ; " Runden"
          waitms 222
        end if
        if Spur_2 = 1 then
          incr Runden
          if Runden > 99 then : Runden =  2 : end if
          Z_formatiert = str(Runden)
          locate 1,12 : lcd ; format(Z_formatiert , "  ") ; " Runden"
          waitms 222
        end if
      loop until Start_Stopp = 1
      rennen = 1
      do : waitms 55 : loop until Start_Stopp = 0
      disable timer0
    return
    
    ' --------------------------------------------------------------------------------------------------------------
    
    Ampelphase:
      Ampel_Z = 0 : blinken =   0
      Ist     = 1 : Soll    = 122				' 122 = normal blinken, 33 = Fehlstart blinken
      enable timer0
      do
        if Ampel_Z < 6 or Soll = 33 then
          if Soll = 33 then : Ampel_Z = 0 : end if
          if blinken = 1 then
            Select case Ampel
              case 0 : locate 2,1 : lcd "- * ------------ * -" : Ampel_1 = 1 : Ampel_2 = 1
              case 1 : locate 2,1 : lcd "- * ------------   -" : Ampel_1 = 1 : Ampel_2 = 0
              case 2 : locate 2,1 : lcd "-   ------------ * -" : Ampel_1 = 0 : Ampel_2 = 1
            end select
          else
            locate 2,1 : lcd "-   ------------   -" : Ampel_1 = 0 : Ampel_2 = 0
          end if
        end if
        if Soll <> 33 then
          if Spur_1 = 1 then
            Fehlstart = 3 : Ampel = 1
          end if
          if Spur_2 = 1 then
            Fehlstart = 4 : Ampel = 2
          end if
        end if
        if Fehlstart > 0 then
          locate Fehlstart,8 : lcd " Fehlstart "
          Fehlstart = 0
          Ist = 1 : Soll = 33
        end if
        gosub Abbruch
      loop until Ampel_Z > 9 or rennen = 0
      locate 2,1 : lcd "--------------------" : Ampel_1 = 0 : Ampel_2 = 0
      disable timer0
    return
    
    ' --------------------------------------------------------------------------------------------------------------
    
    Abbruch:
      If Start_Stopp = 1 then
        locate 2,1 : lcd "--------------------"
        locate 3,8 : lcd "  Abbruch  "
        locate 4,8 : lcd " --------- "
        rennen = 0
        do : waitms 55 : loop until Start_Stopp = 0
      end if
    return
    
    ' --------------------------------------------------------------------------------------------------------------
    
    Timer_0:
      if Ist > Soll then
        Ist = 1
        if blinken = 0 then
          blinken = 1
        else
          blinken = 0
        end if
        incr Ampel_Z
      else
        incr Ist
      end if
    return
    
    ' --- Programm Ende --------------------------------------------------------------------------------------------
    
    end
    
    ' --------------------------------------------------------------------------------------------------------------
    und die Zeilen mit dem Problem:
    Code:
            if Spur_1 = 1 then
              incr Runde_Spur_1
              Z_formatiert = str(Runde_Spur_1)
              locate 3,19 : lcd ; format(Z_formatiert , "  ")
              do : waitms 55 : loop until Spur_1 = 0
            end if
            if Spur_2 = 1 then
              incr Runde_Spur_2
              Z_formatiert = str(Runde_Spur_2)
              locate 4,19 : lcd ; format(Z_formatiert , "  ")
              do : waitms 55 : loop until Spur_2 = 0
            end if
    Was ich brauche ist so etwas:
    Code:
    if Spur_1 = 1 then
      if einfahrt = 0 then
        einfahrt = time + 100
      end if
      if einfahrt < time then
        incr Runde_Spur_1
        Z_formatiert = str(Runde_Spur_1)
        locate 3,19 : lcd ; format(Z_formatiert , "  ")
        einfahrt = 0
      end if
    end if
    Hat Jemand eine Idee zu diesem Problem?

    Grüßle, Naubaddi

  2. #2
    Neuer Benutzer Öfters hier
    Registriert seit
    12.02.2025
    Beiträge
    7
    Hi,

    es funktioniert, wenn auch mit sehr viel mehr Code und Variablen. Da timer0 nicht während dem Rennen benötigt wird kann er jetzt die Durchfahrt der Lichtschranke Spur 1 überwachen, für Spur 2 wurde der timer2 angelegt. Da es jetzt 2 Timer sind mussten alle benötigten Variablen verdoppelt werden, z.B. wurde aus "Ist, Soll" "Ist_1,Ist_2, Soll_1, Soll_2" usw. damit sich die 2 Timer nicht ins Gehege kommen.

    Code:
    ' Compiler: Bascom-Demo 2.0.7.5
    
    ' Dateiname:	Formel X.avr
    ' Funktion:	ein Rundenzähler für Schlitzautos mit einem ATtiny44 auf einem 20x4 Display
    ' Datum:	Start 01.02.2025, Stand 14.02.2025
    ' Von:		Naubaddi foto-schubser@arcor.de
    '
    ' ATtiny44 (B.3 RESET)
    '
    '                                    +----v----+
    '                                VCC | 1     14| GND
    '                   PCINT8/XTAL1 B.0 | 2     13| A.0 ADC0/AREF/PCINT0
    '                   PCINT9/XTAL2 B.1 | 3     12| A.1 ADC1/AIN0/PCINT1
    '               PCINT11/RESET/dW B.3 | 4     11| A.2 ADC2/AIN1/PCINT2
    '        PCINT10/INT0/OC0A/CKOUT B.2 | 5     10| A.3 ADC3/T0/PCINT3
    '           PCINT7/ICP/OC0B/ADC7 A.7 | 6      9| A.4 ADC4/USCK/SCL/T1/PCINT4
    '      PCINT6/OC1A/SDA/MOSI/ADC6 A.6 | 7      8| A.5 ADC5/DO/MISO/OC1B/PCINT5
    '                                    +---------+
    '
    
    ' --- Mikrocontroler Daten... ----------------------------------------------------------------------------------
    
    $regfile   = "attiny44.dat"
    $crystal   = 8000000
    $hwstack   = 40
    $swstack   = 40
    $framesize = 40
    
    ' --- Deklarationen... -----------------------------------------------------------------------------------------
    
    enable interrupts
    
    config timer0 = timer , prescale = 256
    on timer0 Timer_0
    disable timer0
    
    config timer1 = timer , prescale = 1
    on timer1 Timer_1
    disable timer1
    
    config porta  = output
    config portb  = input
    
    config lcdpin = pin , Db4 = porta.2 , Db5 = porta.3 , Db6 = porta.4 , Db7 = porta.5 , E = porta.0 , Rs = porta.1
    config lcd    = 20 * 4
    cursor off    : cls
    
    Ampel_1     alias porta.6       : Ampel_1      =   0	' Spannung für die Ampel Spur 1
    Ampel_2     alias porta.7       : Ampel_2      =   0	' Spannung für die Ampel Spur 2
    Spur_1      alias  pinb.1				' Spur 1 und Auswahl -
    Spur_2      alias  pinb.2				' Spur 2 und Auswahl +
    Start_Stopp alias  pinb.0				' das Rennen starten/stoppen
    
    ' --- Variablen... ---------------------------------------------------------------------------------------------
    
    dim Soll_1        as byte       : Soll_1        = 122	' 122,07 ist ca. eine Sekunde
    dim Ist_1         as byte       : Ist_1         =   1	' Zeit-Zähler bis Ist > Soll erreicht wurde
    dim blinken_1     as Byte       : blinken_1     =   0	' blinken für die Runden, die Ampel, den Fehlstart...
    dim Ampel_Z_1     as byte       : Ampel_Z_1     =   0	' ein Zähler für das blinken der Ampel
    
    dim Soll_2        as byte       : Soll_2        = 122	' 122,07 ist ca. eine Sekunde
    dim Ist_2         as byte       : Ist_2         =   1	' Zeit-Zähler bis Ist > Soll erreicht wurde
    dim blinken_2     as Byte       : blinken_2     =   0	' blinken für die Runden, die Ampel, den Fehlstart...
    dim Ampel_Z_2     as byte       : Ampel_Z_2     =   0	' ein Zähler für das blinken der Ampel
    
    dim Runden        as Byte       : Runden        =  20	' die Anzahl der Runden für ein Rennen
    dim Runde_Spur_1  as Byte       : Runde_Spur_1  =   0	' die gefahrenen Runden auf Spur 1
    dim Spur_1PZ      as Byte       : Spur_1PZ      =   0	' die Prellzeit für Spur 1
    dim Runde_Spur_2  as Byte       : Runde_Spur_2  =   0	' die gefahrenen Runden auf Spur 2
    dim Spur_2PZ      as Byte       : Spur_2PZ      =   0	' die Prellzeit für Spur 2
    dim Ampel         as Byte       : Ampel         =   0	' die Startampel für Spur 1 und/oder Spur 2
    dim Fehlstart     as Byte       : Fehlstart     =   0	' ein Fahrer ist vor dem Startsignal losgefahren
    dim rennen        as byte       : rennen        =   0	' läuft das Rennen? 0 = nein, 1 = ja
    dim Z_formatieren as string * 2 : Z_formatieren =  ""	' Zahlen rechtsbündige formatieren
    
    ' --- Programm Anfang ------------------------------------------------------------------------------------------
    
    Z_formatieren = str(Runden)
    locate 1,1 : lcd "Formel X  " ; format(Z_formatieren , "   ") ; " Runden"
    locate 2,1 : lcd "--------------------"
    locate 3,1 : lcd "Spur 1 ---- Runde  0"
    locate 4,1 : lcd "Spur 2 ---- Runde  0"
    
    do
      gosub Runden_einstellen
      if rennen = 1 then
        Z_formatieren = str(Runden)
        locate 1,12 : lcd ; format(Z_formatieren , "  ") ; " Runden"
        locate 2,1  : lcd "--------------------"
        locate 3,1  : lcd "Spur 1 ---- Runde  0"
        locate 4,1  : lcd "Spur 2 ---- Runde  0"
        gosub Ampelphase
        if rennen = 1 then
          Runde_Spur_1 = 0 : Runde_Spur_2 = 0
          Spur_1PZ     = 0 : Spur_2PZ     = 0
          do
            if Spur_1 = 1 or Spur_1PZ <> 0 then
              if Spur_1PZ = 0 then
                incr Runde_Spur_1
                Z_formatieren = str(Runde_Spur_1)
                locate 3,19 : lcd ; format(Z_formatieren , "  ")
                Ist_1 = 0 : Soll_1 = 122 : Spur_1PZ = 1
                enable timer0
              else
                if Spur_1PZ > 60 then
                  disable timer0
                  Spur_1PZ = 0
                end if
              end if
            end if
            if Spur_2 = 1 or Spur_2PZ <> 0 then
              if Spur_2PZ = 0 then
                incr Runde_Spur_2
                Z_formatieren = str(Runde_Spur_2)
                locate 4,19 : lcd ; format(Z_formatieren , "  ")
                Ist_2 = 0 : Soll_2 = 122 : Spur_2PZ = 1
                enable timer1
              else
                if Spur_2PZ > 60 then
                  disable timer1
                  Spur_2PZ = 0
                end if
              end if
            end if
            if Runde_Spur_1 > Runden then
              rennen = 0 : Ampel_1 = 1
              locate 2,1 : lcd "- * ----------------"
              locate 3,1 : lcd "Spur 1 hat gewonnen "
            end if
            if Runde_Spur_2 > Runden then
              rennen = 0 : Ampel_2 = 1
              locate 2,1 : lcd "---------------- * -"
              locate 4,1 : lcd "Spur 2 hat gewonnen "
            end if
            if rennen = 0 then
              do : waitms 55 : loop until Start_Stopp = 1
              do : waitms 55 : loop until Start_Stopp = 0
              locate 2,1 : lcd "--------------------"
            else
              gosub Abbruch
            endif
          loop until rennen = 0
        end if
      end if
    loop
    
    ' --- Prozeduren, Funktionen... --------------------------------------------------------------------------------
    
    Runden_einstellen:
      Ist_1 = 1 : Soll_1 = 122 : blinken_1 = 0
      enable timer0
      do
        if blinken_1 = 1 then
          locate 1,15 : lcd "      "
        else
          locate 1,15 : lcd "Runden"
        end if
        if Spur_1 = 1 then
          decr Runden
          if Runden <  2 then : Runden = 99 : end if
          Z_formatieren = str(Runden)
          locate 1,12 : lcd ; format(Z_formatieren , "  ") ; " Runden"
          waitms 222
        end if
        if Spur_2 = 1 then
          incr Runden
          if Runden > 99 then : Runden =  2 : end if
          Z_formatieren = str(Runden)
          locate 1,12 : lcd ; format(Z_formatieren , "  ") ; " Runden"
          waitms 222
        end if
      loop until Start_Stopp = 1
      disable timer0
      rennen = 1
      do : waitms 55 : loop until Start_Stopp = 0
    return
    
    ' --------------------------------------------------------------------------------------------------------------
    
    Ampelphase:
      Ist_1 = 1 : Soll_1 = 122 : blinken_1 = 0		' 122 = normal blinken, 33 = Fehlstart blinken
      Ampel_Z_1 = 0 : Ampel = 0
      enable timer0
      do
        if Ampel_Z_1 < 6 or Soll_1 = 33 then
          if Soll_1 = 33 then : Ampel_Z_1 = 0 : end if
          if blinken_1 = 1 then
            Select case Ampel
              case 0 : locate 2,1 : lcd "- * ------------ * -" : Ampel_1 = 1 : Ampel_2 = 1
              case 1 : locate 2,1 : lcd "- * ------------   -" : Ampel_1 = 1 : Ampel_2 = 0
              case 2 : locate 2,1 : lcd "-   ------------ * -" : Ampel_1 = 0 : Ampel_2 = 1
            end select
          else
            locate 2,1 : lcd "-   ------------   -" : Ampel_1 = 0 : Ampel_2 = 0
          end if
        end if
        if Soll_1 <> 33 then
          if Spur_1 = 1 then
            Fehlstart = 3 : Ampel = 1
          end if
          if Spur_2 = 1 then
            Fehlstart = 4 : Ampel = 2
          end if
        end if
        if Fehlstart > 0 then
          locate Fehlstart,8 : lcd " Fehlstart "
          Fehlstart = 0
          Ist_1 = 1 : Soll_1 = 33
        end if
        gosub Abbruch
      loop until Ampel_Z_1 > 9 or rennen = 0
      disable timer0
      locate 2,1 : lcd "--------------------" : Ampel_1 = 0 : Ampel_2 = 0 : Ampel = 0
    return
    
    ' --------------------------------------------------------------------------------------------------------------
    
    Abbruch:
      If Start_Stopp = 1 then
        locate 2,1 : lcd "--------------------"
        locate 3,8 : lcd "  Abbruch  "
        locate 4,8 : lcd " --------- "
        rennen = 0
        do : waitms 55 : loop until Start_Stopp = 0
      end if
    return
    
    ' --------------------------------------------------------------------------------------------------------------
    
    Timer_0:
      if Ist_1 > Soll_1 then
        Ist_1 = 1
        if blinken_1 = 0 then
          blinken_1 = 1
        else
          blinken_1 = 0
        end if
        incr Ampel_Z_1
      else
        incr Ist_1
        incr Spur_1PZ
      end if
    return
    
    Timer_1:
      if Ist_2 > Soll_2 then
        Ist_2 = 1
        if blinken_2 = 0 then
          blinken_2 = 1
        else
          blinken_2 = 0
        end if
        incr Ampel_Z_2
      else
        incr Ist_2
        incr Spur_2PZ
      end if
    return
    
    ' --- Programm Ende --------------------------------------------------------------------------------------------
    
    end
    
    ' --------------------------------------------------------------------------------------------------------------
    Grüßl, Naubaddi

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    12.02.2025
    Beiträge
    7
    Hi,

    habe mal ein Foto von dem fertigen Rundenzähler gemacht, so kann man besser erkennen worum es geht.

    Klicke auf die Grafik für eine größere Ansicht

Name:	Rundenzähler mit ATtiny 44 fertig.jpg
Hits:	7
Größe:	81,2 KB
ID:	36046

    Grüßle, Naubaddi

  4. #4
    Erfahrener Benutzer Robotik Visionär Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    37
    Beiträge
    5.082
    Hallo Naubaddi und Willkommen im Forum

    Sorry für die späte Antwort. Ich würde dein Programm ein bisschen ändern.
    Ich kenne mich mit Bascom nicht aus, dadurch kann ich dir keinen Code zur Verfügung stellen.
    Ich kann es aber als Pseudocode schreiben, den du in Bascom ändern kannst.

    Ich weiß nicht ob Bascom Interrupts unterstützt, wenn ja, dann würde ich diese verwenden.
    In den Interrupt schreibst du (wenn du pro Spur einen Interrupt hast, "x" ist deine Spur):
    Code:
    Runden_Spur_x = Runden_Spur_x + 1
    Oder wenn du einen Pin Change Interrupt hast und beide Spuren in einem Interrupt verarbeitest:
    Code:
    Spur_1_Flanke = Spur_1 und nicht Flankenmerker_Spur_1
    Spur_2_Flanke = Spur_2 und nicht Flankenmerker_Spur_2
    
    if Spur_1_Flanke then
       Runden_Spur_1 = Runden_Spur_1 +1
    endif
    if Spur_2_Flanke then
       Runden_Spur_2 = Runden_Spur_2 +1
    endif
    
    Flankenmerker_Spur_1 = Spur_1
    Flankenmerker_Spur_2 = Spur_2
    Wenn du die Eingänge per Sorftware entprellen willst, dann würde ich eine kurze Zeit wählen (z.B. 1ms) und zum Entprellen zählen. Den Hilfsmerker verknüpfst du mit dem Eingang für die Spur, mit dem du dann den Rundenzähler erhöhst. (Also z.B. Spur1 und nicht Hilfsmerker1 => Rundenzähler + 1)

    Z.B. so
    Code:
    Hauptschleife:
    
    ...
    ...
    ...
    ...
    ...
    ...
    
    if Spur_1_Flanke then
       Hilfsmerker_Spur_1 = 1
       Entprellung_Spur_1 = 0
    endif
    
    if Hilfsmerker_Spur_1 = 1 then
       if Entprellung_Spur_1 < 50 then
          Entprellung_Spur_1 = Entprellung_Spur_1 + 1
       else
          Hilfsmerker_Spur_1 = 0
       endif
    
    Gleicher Ablauf für Spur 2
    Warte 1ms
    Wenn du Interrupts verwendest, dann musst du den Code, den ich in der Hauptschleife geschrieben habe, in den Interrupt geben.

    Solltest du keinen Interrupt verwenden können, dann musst du den gesamten Teil in die Hauptschleife geben.

    Schöner Aufbau, sehr gut.

    edit: Was mir noch aufgefallen ist, ist die Variable "Blinken..." in Timer 0. Dort schreibst du:
    Code:
    if blinken = 1 then
    blinken = 0
    else
    blinken = 1
    endif
    einfacher wäre:
    Code:
    blinken = nicht blinken
    MfG Hannes
    Geändert von 021aet04 (16.02.2025 um 18:08 Uhr)

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    12.02.2025
    Beiträge
    7
    Hi Hannes,

    Danke für die Anregungen und die Beispiele wie man es machen kann.

    Zitat Zitat von 021aet04 Beitrag anzeigen
    ...Ich weiß nicht ob Bascom Interrupts unterstützt...
    Ja, Bascom hat Interrupts welche ich auch benutze: timer0 für Spur 1 und timer1 für Spur 2, es sind die 2 Prozeduren am Ende des Programms. Das Programm funktioniert mittlerweile ja auch sehr zuverlässig, ein paar Verbesserungen und gut ist.

    Zitat Zitat von 021aet04 Beitrag anzeigen
    ...Was mir noch aufgefallen ist, ist die Variable "Blinken..."...
    Die "if Blinken_1 = 0 then..." Schleife wurde auf Dein Anregen durch ein einfaches "toggle Blinken_1" ersetzt.

    Zitat Zitat von 021aet04 Beitrag anzeigen
    ...Wenn du die Eingänge per Sorftware entprellen willst, dann würde ich eine kurze Zeit wählen (z.B. 1ms) ...
    Die Prellzeit muß lang sein weil z.B. das GoKart sehr viele Lücken hat und bei der Durchfahrt ca. 8 Runden zählt , da reicht 1ms nicht aus.

    Klicke auf die Grafik für eine größere Ansicht

Name:	Go-Kart Nr. 23.jpg
Hits:	3
Größe:	51,5 KB
ID:	36048

    So sieht es jetzt aus:

    Code:
    ' Compiler: Bascom-Demo 2.0.7.5
    
    ' Dateiname:	Formel X.avr
    ' Funktion:	ein Rundenzähler für Schlitzautos mit einem ATtiny44 auf einem 20x4 Display
    ' Datum:	Start 01.02.2025, Stand 17.02.2025
    ' Von:		Naubaddi foto-schubser@arcor.de
    '
    ' ATtiny44 (B.3 RESET)
    '
    '                                    +----v----+
    '                                VCC | 1     14| GND
    '                   PCINT8/XTAL1 B.0 | 2     13| A.0 ADC0/AREF/PCINT0
    '                   PCINT9/XTAL2 B.1 | 3     12| A.1 ADC1/AIN0/PCINT1
    '               PCINT11/RESET/dW B.3 | 4     11| A.2 ADC2/AIN1/PCINT2
    '        PCINT10/INT0/OC0A/CKOUT B.2 | 5     10| A.3 ADC3/T0/PCINT3
    '           PCINT7/ICP/OC0B/ADC7 A.7 | 6      9| A.4 ADC4/USCK/SCL/T1/PCINT4
    '      PCINT6/OC1A/SDA/MOSI/ADC6 A.6 | 7      8| A.5 ADC5/DO/MISO/OC1B/PCINT5
    '                                    +---------+
    '
    
    ' --- Mikrocontroler Daten... ----------------------------------------------------------------------------------
    
    $regfile   = "attiny44.dat"
    $crystal   = 8000000
    $hwstack   = 40
    $swstack   = 40
    $framesize = 40
    
    ' --- Deklarationen... -----------------------------------------------------------------------------------------
    
    enable interrupts
    
    config timer0 = timer , prescale = 256			' bei 8 Bit 256 für ca. eine Sekunde
    on timer0 Timer_0
    disable timer0
    
    config timer1 = timer , prescale = 1			' bei 16 Bit 1 für ca. eine Sekunde
    on timer1 Timer_1
    disable timer1
    
    config porta  = output
    config portb  = input
    
    config lcdpin = pin , Db4 = porta.2 , Db5 = porta.3 , Db6 = porta.4 , Db7 = porta.5 , E = porta.0 , Rs = porta.1
    config lcd    = 20 * 4
    cursor off    : cls
    
    Ampel_1     alias porta.6      : Ampel_1      =   0	' Spannung für die Ampel Spur 1
    Ampel_2     alias porta.7      : Ampel_2      =   0	' Spannung für die Ampel Spur 2
    Spur_1      alias  pinb.1				' Spur 1 und Auswahl -
    Spur_2      alias  pinb.2				' Spur 2 und Auswahl +
    Start_Stopp alias  pinb.0				' das Rennen starten/stoppen
    
    ' --- Variablen... ---------------------------------------------------------------------------------------------
    
    dim Soll_1       as byte       : Soll_1       = 122	' 122,07 ist ca. eine Sekunde
    dim Ist_1        as byte       : Ist_1        =   1	' Zeit-Zähler bis Ist_1 > Soll_1 erreicht wurde
    dim blinken_1    as bit        : blinken_1    =   0	' blinken für die Runden, die Ampel, den Fehlstart...
    dim Ampel_Z_1    as byte       : Ampel_Z_1    =   0	' ein Zähler für das blinken der Ampel
    
    dim Soll_2       as byte       : Soll_2       = 122	' 122,07 ist ca. eine Sekunde
    dim Ist_2        as byte       : Ist_2        =   1	' Zeit-Zähler bis Ist_2 > Soll_2 erreicht wurde
    dim blinken_2    as bit        : blinken_2    =   0	' blinken für die Runden, die Ampel, den Fehlstart...
    dim Ampel_Z_2    as byte       : Ampel_Z_2    =   0	' ein Zähler für das blinken der Ampel
    
    dim Runden       as byte       : Runden       =  20	' die Anzahl der Runden für ein Rennen
    dim Runde_Spur_1 as byte       : Runde_Spur_1 =   0	' die gefahrenen Runden auf Spur 1
    dim Spur_1PZ     as byte       : Spur_1PZ     =   0	' die Prellzeit für Spur 1
    dim Runde_Spur_2 as byte       : Runde_Spur_2 =   0	' die gefahrenen Runden auf Spur 2
    dim Spur_2PZ     as byte       : Spur_2PZ     =   0	' die Prellzeit für Spur 2
    dim Ampel        as byte       : Ampel        =   0	' die Startampel für Spur 1 und/oder Spur 2
    dim Fehlstart    as byte       : Fehlstart    =   0	' ein Fahrer ist vor dem Startsignal losgefahren
    dim rennen       as byte       : rennen       =   0	' läuft das Rennen? 0 = nein, 1 = ja
    dim Z_formatiert as string * 2 : Z_formatiert =  ""	' Zahlen rechtsbündige formatieren
    
    ' --- Programm Anfang ------------------------------------------------------------------------------------------
    
    Z_formatiert = str(Runden)
    locate 1,1 : lcd "Formel X  " ; format(Z_formatiert , "   ") ; " Runden"
    locate 2,1 : lcd "--------------------"
    locate 3,1 : lcd "Spur 1 ---- Runde  0"
    locate 4,1 : lcd "Spur 2 ---- Runde  0"
    
    do
      gosub Runden_einstellen
      if rennen = 1 then
        Z_formatiert = str(Runden)
        locate 1,12 : lcd ; format(Z_formatiert , "  ") ; " Runden"
        locate 2,1  : lcd "--------------------"
        locate 3,1  : lcd "Spur 1 ---- Runde  0"
        locate 4,1  : lcd "Spur 2 ---- Runde  0"
        gosub Ampelphase
        if rennen = 1 then
          Runde_Spur_1 = 0 : Runde_Spur_2 = 0
          Spur_1PZ     = 0 : Spur_2PZ     = 0
          do
            if Spur_1 = 1 or Spur_1PZ <> 0 then
              if Spur_1PZ = 0 then
                Ampel_1 = 1 : locate 2,1 : lcd "- * -"
                incr Runde_Spur_1 : Z_formatiert = str(Runde_Spur_1)
                locate 3,19 : lcd ; format(Z_formatiert , "  ")
                Ist_1 = 0 : Soll_1 = 222 : Spur_1PZ = 1
                enable timer0
                Ampel_1 = 0 : locate 2,1 : lcd "-----"
              else
                if Spur_1PZ > 120 then
                  disable timer0
                  Spur_1PZ = 0
                end if
              end if
            end if
            if Spur_2 = 1 or Spur_2PZ <> 0 then
              if Spur_2PZ = 0 then
                Ampel_2 = 1 : locate 2,16 : lcd "- * -"
                incr Runde_Spur_2 : Z_formatiert = str(Runde_Spur_2)
                locate 4,19 : lcd ; format(Z_formatiert , "  ")
                Ist_2 = 0 : Soll_2 = 222 : Spur_2PZ = 1
                enable timer1
                Ampel_2 = 0 : locate 2,16 : lcd "-----"
              else
                if Spur_2PZ > 120 then
                  disable timer1
                  Spur_2PZ = 0
                end if
              end if
            end if
            if Runde_Spur_1 > Runden then
              rennen = 0 : Ampel_1 = 1
              locate 2,1 : lcd "- * -"
              locate 3,1 : lcd "Spur 1 hat gewonnen "
            end if
            if Runde_Spur_2 > Runden then
              rennen = 0 : Ampel_2 = 1
              locate 2,16 : lcd "- * -"
              locate 4,1  : lcd "Spur 2 hat gewonnen "
            end if
            if rennen = 0 then
              do : waitms 55 : loop until Start_Stopp = 1
              do : waitms 55 : loop until Start_Stopp = 0
              locate 2,1 : lcd "--------------------"
              Ampel_1 = 0 : Ampel_2 = 0
            else
              gosub Abbruch
            endif
          loop until rennen = 0
        end if
      end if
    loop
    
    ' --- Prozeduren, Funktionen... --------------------------------------------------------------------------------
    
    Runden_einstellen:
      Ist_1 = 1 : Soll_1 = 122 : blinken_1 = 0
      enable timer0
      do
        if blinken_1 = 1 then
          locate 1,15 : lcd "      "
        else
          locate 1,15 : lcd "Runden"
        end if
        if Spur_1 = 1 then
          decr Runden
          if Runden <  2 then : Runden = 99 : end if
          Z_formatiert = str(Runden)
          locate 1,12 : lcd ; format(Z_formatiert , "  ") ; " Runden"
          waitms 222
        end if
        if Spur_2 = 1 then
          incr Runden
          if Runden > 99 then : Runden =  2 : end if
          Z_formatiert = str(Runden)
          locate 1,12 : lcd ; format(Z_formatiert , "  ") ; " Runden"
          waitms 222
        end if
      loop until Start_Stopp = 1
      disable timer0
      rennen = 1
      do : waitms 55 : loop until Start_Stopp = 0
    return
    
    ' --------------------------------------------------------------------------------------------------------------
    
    Ampelphase:
      Ist_1 = 1 : Soll_1 = 122 : blinken_1 = 0		' 122 = normal blinken, 33 = Fehlstart blinken
      Ampel_Z_1 = 0 : Ampel = 0
      enable timer0
      do
        if Ampel_Z_1 < 6 or Soll_1 = 33 then
          if Soll_1 = 33 then : Ampel_Z_1 = 0 : end if
          if blinken_1 = 1 then
            Select case Ampel
              case 0 : locate 2,1 : lcd "- * ------------ * -" : Ampel_1 = 1 : Ampel_2 = 1
              case 1 : locate 2,1 : lcd "- * ------------   -" : Ampel_1 = 1 : Ampel_2 = 0
              case 2 : locate 2,1 : lcd "-   ------------ * -" : Ampel_1 = 0 : Ampel_2 = 1
            end select
          else
            locate 2,1 : lcd "-   ------------   -"
            Ampel_1 = 0 : Ampel_2 = 0
          end if
        end if
        if Soll_1 <> 33 then
          if Spur_1 = 1 then
            Fehlstart = 3 : Ampel = 1
          end if
          if Spur_2 = 1 then
            Fehlstart = 4 : Ampel = 2
          end if
        end if
        if Fehlstart > 0 then
          locate Fehlstart,8 : lcd " Fehlstart "
          Fehlstart = 0
          Ist_1 = 1 : Soll_1 = 33
        end if
        gosub Abbruch
      loop until Ampel_Z_1 > 9 or rennen = 0
      disable timer0
      locate 2,1 : lcd "--------------------"
      Ampel_1 = 0 : Ampel_2 = 0 : Ampel = 0
    return
    
    ' --------------------------------------------------------------------------------------------------------------
    
    Abbruch:
      If Start_Stopp = 1 then
        locate 2,1 : lcd "--------------------"
        locate 3,8 : lcd "  Abbruch  "
        locate 4,8 : lcd " --------- "
        rennen = 0
        do : waitms 55 : loop until Start_Stopp = 0
      end if
    return
    
    ' --------------------------------------------------------------------------------------------------------------
    
    Timer_0:
      if Ist_1 > Soll_1 then
        Ist_1 = 1
        toggle blinken_1
        incr Ampel_Z_1
      else
        incr Ist_1
        incr Spur_1PZ
      end if
    return
    
    Timer_1:
      if Ist_2 > Soll_2 then
        Ist_2 = 1
        toggle blinken_2
        incr Ampel_Z_2
      else
        incr Ist_2
        incr Spur_2PZ
      end if
    return
    
    ' --- Programm Ende --------------------------------------------------------------------------------------------
    
    end
    
    ' --------------------------------------------------------------------------------------------------------------
    Grüßle, Hermann
    Geändert von Naubaddi (17.02.2025 um 12:09 Uhr) Grund: Bild eingefügt.

  6. #6
    Erfahrener Benutzer Robotik Visionär Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    37
    Beiträge
    5.082
    Ich meinte nicht das du nur 1ms misst.

    In der Hauptschleife fügst du ein delay von 1ms ein (somit hast du einen Schleifendurchlauf von Programmablauf + 1ms).
    Wenn die Lichtschranke ein Fahrzeug erkennt (und vorher noch keines erkannt wurde) setzt du einen Merker (=Fahrzeug erkannt).
    Gleichzeitig setzt du einen Counter auf 0.
    Wenn du ein Fahrzeug erkannt hast (Merker) zählst du in jedem Schleifendurchlauf den Counter hoch.
    Wenn der Counter z.B. 50 erreicht hat (entspricht mindestens 50ms), dann gibst du die die Fahrzeugerkennung wieder frei (Merker "Fahrzeug erkannt" wieder auf "0" setzen).


    Ich hoffe das du es jetzt besser verstanden hast was ich meine.

    Edit: Den Merker benötigst du natürlich für jede Spur ein mal.

    MfG Hannes

Ähnliche Themen

  1. 2-Timerprobleme kann ich nicht lösen(Attiny13 o.ä)
    Von oderlachs im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 9
    Letzter Beitrag: 17.02.2014, 16:05
  2. PCF8574 funktioniert nur nicht beim Lesen, warum?
    Von madangdive im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 06.01.2010, 12:43
  3. ATtiny44 ADC will nicht
    Von Schokohoernl im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 4
    Letzter Beitrag: 07.07.2007, 14:51
  4. URXC1 Interrupt beim Atmega 128 funktioniert nicht
    Von tobuc0 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 0
    Letzter Beitrag: 24.06.2007, 10:23
  5. kann Uref beim Roboterboard V1.2 nicht messen
    Von Marvin im Forum Bauanleitungen, Schaltungen & Software nach RoboterNetz-Standard
    Antworten: 2
    Letzter Beitrag: 30.04.2004, 23:43

Berechtigungen

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

LiFePO4 Speicher Test