Sterrenhemel

Dit topic is gesloten

Bavelt

Golden Member

Ja, die had ik al geprobeerd. Hardnekkig probleem, hoor..

Ik had ook al een testled opgenomen, om te zien waar het programma nu precies wel of niet komt.

De IR-ontvangst gaat goed. Ook de timer werkt met interrupts van 100uS.
De display-routine op de LCD werkt ook. Dat kan ik testen door een paar testregels in de interrupt toe te voegen, waabij ik IRCode vul met een constante.

pic basic code:

IRCode="12345678901234567890123456789012"
     fIRFound = 1

Dat wordt dan keurig getoond.

Het gaat fout bij de vatstelling of er een geldige puls is ontvangen.
Hij ziet nooit een o of een 1...

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Je kunt simpel met een led of pin / LA testen waar je wel en niet komt.

code:

If (HiCnt = TIMEOUT) And (LoCnt = TIMEOUT) Then 

Hier moet je iedere pulstrein 1x komen

code:


If (HiCnt > MINHI) And                                     
   (HiCnt < MAXHI) And                                     
   (LoCnt > MINLO) And                                     
   (LoCnt < MAXLO) Then                                    

en hier 32 keer...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

If (HiCnt = TIMEOUT) And (LoCnt = TIMEOUT) Then...

Er komt al wat muziek uit de tent..

Maar alleen bij If (HiCnt = TIMEOUT) OR (LoCnt = TIMEOUT).. Then

Het komt nl niet voor dat zowél de Hi als de Lo een timeout geeft...

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Dat moet wel, anders wordt 't niet betrouwbaar...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Het schiet wel op. Wat er nu overblijft is dat er altijd een goed resultaat komt als ik de knop indruk van het programmaatje dat de puls simuleert.

De IR doet het af-en-toe. Soms wel, soms niet.
Er zit dus blijbaar een klein verschil tussen wat ik zelf fabriceer en wat de IR afgeeft.

De Puls-emulatie komt rechtstreeks uit een PIC-poort.

De IR is met een weerstand van 470 Ohm naar de +5V gekoppeld (ik las dat je dat moet doen om de stroom te begrenzen), en een elcootje van 10uF rechtstreeks op de + en - van de TSOP.
Daarbij is de output voorzien van een pullup weerstand van 10K naar de +5V.

Ik meet op de scoop een puls van ca 4vtt van de IR, de PIC geeft keurig 5V.

Kleine verschillen mnoeten maken dat de IR onstabiel is.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Het grappige is dat vandaag een aantal TSOP1736's binnenkwam.

De TSOP waarmee ik testte, kwam van de vakhandel. Ook een TSOP1736.

Die ik vandaag kreeg zijn van tante Alie. Dus ik stopte er maar even eentje van in het breadboard.
Deze lijken veel stabieler...Ik krijg nu al een poosje steeds een goed resultaat..

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Ik denk dat de puls uit de tsop niet 'netjes is'. Probeer MINLO en MINHI eens op 3 te zetten...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Op 13 november 2020 23:31:34 schreef Arco:
Ik denk dat de puls uit de tsop niet 'netjes is'. Probeer MINLO en MINHI eens op 3 te zetten...

Dat lijkt idd soelaas te bieden.. ;)

Nou, dan ben ik nu een heel eind. En weer veel geleerd, Dank Arco, voor al je inzet...

Het werken met Pulseview en de Analyzer is best wel leuk. Je kan alle tijden precies zien, een 'opname' maken, etc.
Grappig hoor...

Als dit stabiel blijft en blijkt, dan kan ik verder met de sterrenhemel, het eigenlijke topic.

Wat ik me nu nog afvroeg: Ik heb het nu gedaan met IR. Maar was een andere oplossing wellicht ook net zo slim geweest? Bv via bluetooth, of met zo'n 433 Mhz garagedeur-ABtje?

Ik heb ca 5 - 6 knoppen nodig om het geheel te bedienen.

Of is dat IR wel de gekijke methode? Die NEC is wel een mooi klein dingetje...

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Ik vond in de nachtelijke zoektochten ( :/ ) een hit van iemand de ook met MikroBasic een NEC remote uitleest.

Die deed dat met een PIC12F629. Dat is vast een oud beestje? De enige 12F die ik heb is de PIC12F1572. Ze hebben wel dezelfde pinindeling.
Bij de 629 noemt men de poorten anders: bv GP5 ipv RA5.

Oud spul?

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Zou met wat kleine wijzigingen wel moeten werken. (wat andere registernamen zoals inderdaad PORTA i.p.v. GPIO)
Ik vind IR voor zoiets altijd heel handig. Voordeel: je hebt nooit last van storing door andere zenders...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Nou, het programma werkt nu helemaal goed!

Ik zet het complete 'project' maar hier op het forum. Wellicht wil ooit iemand ook met een NEC Data Infrarood remote control EN MikroBasic wat doen.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Ondertussen ga ik ook wat verder spelen met de Logic Anlyzer en het open source programma PulseView. Best heel leuk om te doen.
Zo zag ik dat het programma een aantal standaard decoders in zich heeft, waar je deze kunt vergelijken met je eigen output.

Het enig dat me nog niet is gelukt is om de 'kanalen' individueel te verschuiven.

Dan zou je 2 pulsen onder elkaar kunnen 'schuiven' om te vergelijken. Ik heb nog niet ontdekt hoe dat kan. Misschien kan het ook wel niet.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Ik ontvang nu een string met de waarde vanuit de IR-receiver. In principe heb ik alleen de Command-Code nodig. Deze staat op postie 16 - 23 in de string.
Ik filter die er uit en stop de waarde in string Charx [8]

Met de ontvangen waarden wil je natuurlijk wat.
Als ik op knop 1 van de AB druk, wordt het "10100010". Prima.

Maar wanneer ik

pic basic code:

if (strCmp(CharX, "10100010") = 0) then Str = "Gelijk" Else Str =  "Ongelijk" End if

doe, dan ziet hij ze niet als gelijk (althans, geen resultaat = 0).

Ik dacht even misschien dat de volgorde andersom moet, dus "01000101", maar ook dat is ongelijk.

Of gebruik ik het statement verkeerd?

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Zou gewoon moeten werken. Zijn de strings inderdaad wel gelijk?

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Op 14 november 2020 23:38:57 schreef Arco:
Zou gewoon moeten werken. Zijn de strings inderdaad wel gelijk?

Nee dus... ;(

Initieel werd de string niet leegemaakt en kan er dus rommel in zitten.

Nu gaat het goed.

Nu nog even zoeken naar een slimme oplossing om de codes en de gewenste functies op te nemen. Het mooiste zou zijn met een tabel.
Jammer dat je niet

pic basic code:

if str = "12345" then ...

mag opgeven, dan had het mooi met een select case o.i.d gekund.

Onderstaande constructie werkt wel maar is wat boerenkool-achtig..
:D

pic basic code:

  if (strCmp(CharX, "10100010") = 0) then Str = "Toets 1"  End if
  if (strCmp(CharX, "01100010") = 0) then Str = "Toets 2"  End if
  if (strCmp(CharX, "11100010") = 0) then Str = "Toets 3"  End if
Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Ik heb zelf al iets gevonden in de goede richting.

Ik hoef natuurlijk niet perse met strings te werken.

Als ik de code in een Byte plaats en die byte koppel aan een functie gaat het mooier:

pic basic code:

For i1 = 16 to 23
     if(IRCode[i1] = "0") then CodeByte.(i1-16) = 0 else CodeByte.(i1-16) = 1 End if
Next i1

  Select case CodeByte
  Case 69
       Str = "Toets 1"
  Case 70
       Str = "Toets-2"
  Case 71
       Str = "Toets-3"
  Case Else
       BytetoStr(CodeByte, Str)
       Str = Str + " Onbekend"
  End Select
Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Op 15 november 2020 13:15:19 schreef Bavelt:
Ik heb zelf al iets gevonden in de goede richting.

Ik hoef natuurlijk niet perse met strings te werken.

Als ik de code in een Byte plaats en die byte koppel aan een functie gaat het mooier:

pic basic code:

For i1 = 16 to 23
     if(IRCode[i1] = "0") then CodeByte.(i1-16) = 0 else CodeByte.(i1-16) = 1 End if
Next i1

  Select case CodeByte
  Case 69
       Str = "Toets 1"
  Case 70
       Str = "Toets-2"
  Case 71
       Str = "Toets-3"
  -
  -
  Case Else
       BytetoStr(CodeByte, Str)
       Str = Str + " Onbekend"
  End Select

En zonder het gebruik van een LCD (wat uiteindelijk ook gaat gebeuren) kan in de interrupt routine de Byte mneteen worden gevuld. Dat scheelt weer conversies etc.

[Bericht gewijzigd door Bavelt op zondag 15 november 2020 13:20:00 (11%)

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Voor de geinteresseerden ook de RC-5 versie. (iets lastiger, vanwege de Manchester code... ;) )
Processor is 16f1709, commandocode wordt getoond op port C

pic basic code:


'======================================================================================
Program Test  'Philips RC5 protocol

Const MINPULS  = 5           'Minimal value pulse
      MEDPULS  = 12          'Medium value pulse
      MAXPULS  = 22          'Maximal value pulse
      TIMEOUT  = 200         'Max count timeout
      
Dim PulseCnt     As Byte
    IRCmd        As Byte
    IRAddr       As Byte
    HiLoCnt      As Byte

    Flags        As Byte
      fPrev      As sBit At Flags.0   'Previous state of input
      fIRFound   As sBit At Flags.1   'Detect done
      fShift     As sBit At Flags.2
      fToggle    As sBit At Flags.3
      
Dim IRIn         As sBit At PORTB.7

'========================================================================================
Sub Procedure Init()
'========================================================================================
  TRISA = %00011100     LATA = %00100000     ANSELA = %00000000     'Port direction, type
  TRISB = %10000000     LATB = %00000000     ANSELB = %00000000     '(a/d), and in/out
  TRISC = %00000000     LATC = %00000000     ANSELC = %00000000     'settings
  '--------------------------------------------------------------------------------------
  OSCCON  = %11110000                                               'Oscillator
  T2CON   = %00011100   PR2      = 199                              'Timer2:post4, pre1
  GIE_bit = 1           PEIE_bit = 1    TMR2IE_bit = 1              'Interrupts on
  fPrev   = IRIn                                                    '
  IRCmd   = 0                                                       '
  IRAddr  = 0                                                       '
End Sub                                                             '

'========================================================================================
Sub procedure Interrupt() iv 0x0004 ics ICS_AUTO
'========================================================================================
  If TMR2IF_bit Then                                                'Timer Interrupt?
    If fIRFound = 0 Then                                            'Prev code handled?
      If (IrIn = fPrev) Then                                        'Input not changed?
        If PulseCnt < TIMEOUT Then Inc(PulseCnt) End If             'Increment pulse
      Else                                                          'Input changed
        If PulseCnt = TIMEOUT Then                                  'New pulse
          HiLoCnt = 0   PulseCnt = 0   IRCmd = 0   IRAddr  = 0      '
        End If                                                      '
        If (PulseCnt > MINPULS) And (PulseCnt < MAXPULS) Then       'See if valid
          Inc(HiLoCnt)                                              'Add 1/2 to count
          If PulseCnt > MEDPULS Then Inc(HiLoCnt) End If            '
          Select Case HiLoCnt                                       '
            Case 2                 fShift = not IrIn                'Shift bit
            Case 4                 fToggle = not IrIn               'Toggle bit
            Case 6,8,10,12,14      IRAddr = IRAddr << 1 Or not IrIn 'Address
            Case 16,18,20,22,24,26 IRCmd  = IRCmd << 1 Or not IrIn  'Command
          End Select                                                '
          PulseCnt = 0                                              '
        End If                                                      '
      End If                                                        '
      If HiLoCnt = 26 Then fIRFound = 1  End If                     'Found detect
      fPrev = IrIn                                                  'Update state
    Else                                                            '
      HiLoCnt = 0 PulseCnt = 0                                      'Clear counters
    End If                                                          '
    TMR2IF_bit = 0                                                  '
  End If                                                            '
End Sub                                                             '

'========================================================================================

Main:

  Init()
  While True
    If fIRFound Then
      LATC = IRCmd
      Delay_ms(1000)
      LATC = %00000000
      fIRFound = 0
    End If
  Wend
End.
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Grappig, ik heb nl gisteren een RC5 Remote bemachtigd. Daar wilde ik na dit project ook al mee gaan spelen.

Ik had in eerste instantie het idee dat de RC5 makkelijker is dan de NEC, omdat deze niet werkt met tussenpauzes die bepalen of het een 0 of 1 is.

Maar het is dus iets lastiger begrijp ik...Maakt niet uit.

Waar ik zelf nog even mee worstel: ik gebruik de timer interrupt nu ook in het Sterrenhemel programma. Dat werkt goed. ;)

In de Main wordt dan afgevangen if interrupt then ...etc.

Maar dat levert dan wel een vertraging op, van soms wel 9 seconden.
Dat komt omdat in het mainprogramma functies zitten die 9 seconden moeten wachten. (wisseling van ster).
Dit gebeurt dan met delay_ms(9000). Eenmaal in de delay zit-ie er in en moet je de rit uitzitten....

Terwijl je bij bijvoorbeeld de functie "Uit" wilt dat hij vrijwel meteen uitgaat.

Is daar een techniek voor om dit te tackelen? (Wellicht helemaal geen delay gebruiken?)

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

In de interrupt een variabele als countdown bijhouden (iedere interrupt aftrekken tot 'ie nul is.)
Je hoeft dan alleen in main de variabele met de gewenste waarde te laden, en te testen of 'ie weer 0 is...

In de RC5 code staat het commando in IRCmd, het adres in IRAddr.
De flag fShift is de shift status. (hiermee kun je de 64 commando's uitbreiden tot 128).
De flag fToggle wisselt na iedere toetsdruk, om te kunnen zien of het een nieuwe uitzending betreft, of een onderbroken bestaande uitzending...

[Bericht gewijzigd door Arco op zondag 15 november 2020 21:12:06 (42%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Is daar een techniek voor om dit te tackelen? (Wellicht helemaal geen delay gebruiken?)

State machine icm wat @Arco al noemde.

It's the rule that you live by and die for It's the one thing you can't deny Even though you don't know what the price is. It is justified.
Bavelt

Golden Member

In de interrupt een variabele als countdown bijhouden (iedere interrupt aftrekken tot 'ie nul is.)
Je hoeft dan alleen in main de variabele met de gewenste waarde te laden, en te testen of 'ie weer 0 is...

Dit is idd wel een aardige om de vertraging te regelen.

Wat ik doe is in de Main eerst afvragen of er een IR -interrupt is (die gaat voor alles, dat zijn je commando's).

Vervolgens gaat het programma alleen verder bij timercounter = 0 :

pic basic code:

While True
     If fIRFound = 1 then
         Control_IRCode()
         fIRFound = 0
     End If
     If TimerCnt = 0 then
     ---
     --- 
     --- 
     Timercounter = 50000   'Delay 5 sec
     Wend

Nu is het zo dat in de code op andere plekken óók een delay moet zijn.
Is de truc dan om daar eveneens een counter voor te maken die je ook opneemt in de Interrupt routine? Dan zou je voor elke delay in je programma een 'eigen' counter hebben.

Doe ik dat goed?

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Je kunt meerdere timers maken. Makkelijkst is eerst tot 25mS (byte kan niet veel verder), en dan nog een paar timers die * 25mS tellen.
(je kunt ook words of dwords gebruiken, maar da's een veel hogere belasting voor een 8 bitter...)
Zo maak je over het algemeen meestal timers in een interrupt...

pic basic code:



Interrupt: (0.1mS)

  If TmrCnt Then                          'TmrCnt is 25mS timer
    Dec(TmrCnt)
    If TmrCnt = 0 Then 
      TmrCnt = 250 
      If Tmr1Cnt Then Dec Tmr1Cnt End If  'Timer * 25mS
      If Tmr2Cnt Then Dec Tmr2Cnt End If  'Timer * 25mS  
      If Tmr3Cnt Then Dec Tmr3Cnt End If  'Timer * 25mS
      ... 
      ...
    End If
  End If
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Ik had idd Longints gebruikt. Die zijn dan dus ook belastender voor de pic.

Op zich vind ik het al heel wat dat ik 8 LED-matrixen van 8*8 Leds en de IR-sensor aan één PIC16F1847 heb hangen. (Ik ben een beetje gewend geraakt aan dit ding. Veelzijzig, goed te verkrijgen en nog nog gewoon goedkoop ook.)

De sterrenhemel nadert zijn voltooiing. D.w.z. softwarematig. Het monteren van 8 panelen zachtboard van 120 * 60 cm, gaatjes boren, de 512 leds er in en dan er matrixen van maken is een ander verhaal... :O

Daar moet ik eens goed voor gaan zitten hoe ik dat ga doen. Ik heb sowieso 8 MAX7219's nodig. Het beste lijkt om per paneel (= matrix) een aansluiting te maken voor de pic. Dan kan ik ze nog loskoppelen. Misschien handig om de voorgemonteerde printjes met de MAX-en te gebruiken. Die hebben al een connector waar je dupont-wires in kan stoppen.

Handenarbeid...

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Ik heb er ook een Commando RESET in gestopt. De 'hemel' opnieuw opstarten..
in de MB help staat dat RESET() alleen geldt voor de P18...

Maar hij werkt gewoon bij mijn PIC16F1847.. :)
Foutje in de doc?

Fouten zijn het bewijs dat je het probeert..

Dit topic is gesloten