Sterrenhemel

Dit topic is gesloten

Arco

Special Member

Ik neem aan dat RC5In() de naam van een of andere functie is die zijn input van de RC5In_pin krijgt...

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

Golden Member

Op 6 november 2020 22:11:19 schreef Arco:
Ik neem aan dat RC5In() de naam van een of andere functie is die zijn input van de RC5In_pin krijgt...

Kan ik niet zien..Dit is het programma (PicBasic)

pic basic code:

'*  Name    : UITLEZEN RC5 CODE MET 16F887.                                     
'*  Author  : H.van Zwieten.                                    
'*  Notice  : Copyright (c) 2009 H.v.Z.                         
'*          : All Rights Reserved                               
'*  Date    : 30-12-2009                                       
'*  Version : 1.0                                               
'*  Notes   : 468 programma woorden en 21 variabele gebruikt.                                                  
                                                   
Device 16F887                          ; Processor type

Xtal 10                                ; Kristal 10MHz

Asm                                    ; Config settings
CONFIG_REQ            
__CONFIG _CONFIG1, HS_OSC & WDT_OFF & DEBUG_OFF & FCMEN_OFF & LVP_OFF & IESO_OFF & BOR_OFF & CPD_OFF & CP_OFF & MCLRE_OFF & PWRTE_ON 
__CONFIG _CONFIG2, WRT_OFF & BOR40V 
EndAsm

All_Digital true                       ; Alle poorten digitaal

Declare LCD_RSPin PORTD.2              ; Reset display poort D.2
Declare LCD_ENPin PORTD.3              ; Enable display poort D.3
Declare LCD_DTPin PORTD.4              ; Data display poort D.4 t/m D.7

Declare RC5In_Pin PORTB.0              ; ir ontvanger op poort B.0
                                                                                               
Dim rc5_commando As Byte               ; variabele RC5 commando 

Cls                                    ; Wis display

Clear                                  ; Wis geheugen 

DelayMS 2000                           ; Wacht 2 seconden

         ;543210                       ; Hulpregel poort A
PORTA  = %000000                       ; Maak poort A laag
TRISA  = %000000                       ; Poort_A I/O

         ;543210                       ; Hulpregel poort B
PORTB  = %000000                       ; Maak poort B laag
TRISB  = %000001                       ; Poort_B I/O

         ;76543210                     ; Hulpregel poort C
PORTC  = %00000000                     ; Maak poort C laag
TRISC  = %00000000                     ; Poort_C I/O

         ;76543210                     ; Hulpregel poort D
PORTD  = %00000000                     ; Maak poort D laag
TRISD  = %00000000                     ; Poort_D I/O

         ;210                          ; Hulpregel poort E 
PORTE  = %000                          ; Maak poort E laag
TRISE  = %000                          ; Poort_E I/O

         ;76543210                     ; Hulpregel analoog
ADCON0 = %00000001                     ; ADCON0 register analoog 8 bit




         ;76543210                     ; Hupregel analoog
;ADCON1 = %10000000                    ; ADCON1 register analoog 10 bit

         ;76543210                     ; Hulpregel analoog poort_B
;ANSELH = %00000000                    ; ANSEL register analoog poort_B

;---------------------------------
; PROGRAMMA UITLEZEN IR COMMANDO.
;---------------------------------

start:                                        

Print At 1,1,"COMMANDO"                ; Zet commando op het display
Repeat                                 ; herhaal 
rc5_commando = RC5In                   ; Lees ir ingang
Until rc5_commando <> 255              ; Waarde 0 t/m 255 
Print At 1,10,Dec rc5_commando , "  "  ; Zet waarde op display
GoTo start                                    

End 
Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Ik zie het al... Het is een routine in PicBasic...Tja..
Die kent MikroBasic natuurlijk niet...Hmm

[Bericht gewijzigd door Bavelt op vrijdag 6 november 2020 22:41:04 (28%)

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Met deze ogenschijnlijk simpele Arduino sketch kan ik de IR uitlezen

c code:

void setup() {
    // Initialize IR sensor at pin 2
    EasyIR::init(2);

    // Start Serial at speed 9600
    Serial.begin(9600);
}

void loop() {
    // Read from IR, returns 0 if nothing to be read
    long result = EasyIR::read();

    // If there was data to be read, write the result to serial.
    if(result)
    {
        Serial.println(result);
    }

    // Wait 100 msec
    delay(100);
}




/* EasyIR.cpp - an Arduino library for infrared communication intended for educational purposes,
 * especially adapted by Simon Pauw for the Simple Walker II project (simplewalker.com).
 * This library is built on IRRemote V2.2.0 which is released under GNU LESSER GENERAL PUBLIC LICENSE as is this library.
 */

#ifndef EasyIR_h
#define EasyIR_h
#include <Arduino.h>

class EasyIR {
public:
     static void init(int pin);
     static long read();
};


#endif EasyIR_h

Maar hoe zet ik dit nu om in MikroBasic...

Fouten zijn het bewijs dat je het probeert..
Lambiek

Special Member

Op 6 november 2020 22:40:36 schreef Bavelt:
Ik zie het al... Het is een routine in PicBasic...Tja..
Die kent MikroBasic natuurlijk niet...Hmm

Als dat commando niet bestaat in micro basic werkt dat niet natuurlijk.

En hoe je dat om moet zetten zou ik ook niet weten. Mischien weet Arco het.

Als je haar maar goed zit, GROETEN LAMBIEK.
Arco

Special Member

Volgens de comments in de code staat de routine in EasyIR.cpp bij de Arduino...

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

Golden Member

Op 7 november 2020 01:33:32 schreef Arco:
Volgens de comments in de code staat de routine in EasyIR.cpp bij de Arduino...

Die had ik gezien...Maar snap er geen jota van wat hier nu allemaal gebeurt.

Ik blijf dat altijd een worsteling vinden met dat Arduino en de 'included'.h files die elders staan. Ik mis daardoor het overzicht.

In de .h file:

pic basic code:

 class EasyIR {
public:

     static void init(int pin);
     static long read();
};

Wat is nu die "static long read(); " ?

en: long EasyIR::read(); in het programma ?

Wat ik van de IR begrijp, is dat de TSOP sensor hoog geeft in rust. Bij een inkomend signaal komt er een pulstreintje. Afhankelijk van merk/type is die pulstrein anders (lengte, frequentie).
Op zich maakt dat niet uit, als het maar is te herleiden.

Wat ik dan wil, is die pulstrein vastleggen, zodat er een string aan tekens overblijft waar je wat mee kunt doen in het ontvangende programma.
Maar hoe 'capture' ik nu die string?

In Bluetooth kon ik dat doen met een interrupt, waarbij ieder karakter een interrupt gaf. Dan kon ik de string samenstellen.

Maar nu is het een ander verhaal...

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Ik probeer een C-oplossing om te zetten naar MikroBasic

Weet iemand wat hier nu staat:

c code:

if (RBIF_bit && (PORTB.F0 || !PORTB.F0)){         // PORTB change ISR
Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Volgens mij een gecompliceerde (en moeilijk te lezen) versie van dit: ;)

pic basic code:


if (RBIF_bit And (PORTB.F0 Xor 1))     'PORTB change ISR
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Op 7 november 2020 16:37:45 schreef Arco:
Volgens mij een gecompliceerde (en moeilijk te lezen) versie van dit: ;)

pic basic code:


if (RBIF_bit And (PORTB.F0 Xor 1))     'PORTB change ISR

Dat had ik er zelf niet uit gehaald... ;) (Dat C vind ik sowieso slecht te lezen. Mede hierdoor vind ik het Arduino gebeuren niet leuk).

Ik zat in de buurt van if RBIF_bit and PORTB = Not PortB,
m.a.w. een timer interrupt alsmede een wisseling van waarde op Poort B. Maar ik zal de Xor versie overnemen,

Wat bedoelen ze daarnaast eigenlijk met PORTB.F0. Waar komt die F vandaan?

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Nog zo eentje:

Wat moet ik hier nu van maken? Zelfs met een beetje googelen kan ik daar geen chocola van maken..

c code:

 nec_code |= (unsigned long)1 << (31 - i);  
Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Ik weet het, ik heb onlangs 200+ pagina's van dit soort brij om moeten zetten... ;)

pic basic code:


If nec_code <> LongWord 1 << (31-i) Then
  ...
End If
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Ik zit toch echt een beetje vast.

Ik moet dus de interrupt voor zowel de timer overflow zetten, als het enabelen van de interrupt op poort B.0

Dit is uit de datasheet

Maar hoe zet ik nu de waarden?

Verder dan dit kom ik niet:

pic basic code:

GIE_bit    = 1                                'Enable timer1 irq
  PEIE_bit   = 1                                '
  TMR2IE_bit = 1                                '

  TMR1IF_bit = 0                                'Clear Timer1 overflow 


en RBIF kent de  PIC16F1847 niet
Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Op 7 november 2020 21:26:55 schreef Arco:
Ik weet het, ik heb onlangs 200+ pagina's van dit soort brij om moeten zetten... ;)

pic basic code:


If nec_code <> LongWord 1 << (31-i) Then
  ...
End If

Ik word er echt een beetje gek van. 8)7 Hoe kan men nu zoiets bedenken?

c code:

if( timer_value > 1000)                           // If space width > 1ms (short space)
         nec_code |= (unsigned long)1 << (31 - i);         // Write 1 to bit (31 - i)
       else                                                // If space width < 1ms (long space)
         nec_code &= ~((unsigned long)1 << (31 - i));     // Write 0 to bit (31 - i)
       i++;
       if(i > 31){                                  // If all bits are received
         nec_ok = 1;                                // Decoding process OK
         RBIE_bit = 0;                              // Disable PORTB change interrupt
         break;
       }

Dit is het stukje code die blijkbaar waarden zet in de velden.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

IOCBP (positive edge) en IOCBN (negative edge) zijn de enable bits, IOCBF zijn de statusflags.

Ik vind de Watcom reference manual altijd handig om 'rare' C zaken op te zoeken: ftp://ftp.openwatcom.org/manuals/current/clr.pdf

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

Golden Member

Nou, ik heb zo goed en kwaad als het kan de bits en flags opgenomen. Hieronder is het totale programma. Ik denk dat ik ze wellicht niet goed of op de juiste plek heb gezet.

Als je mee zou willen kijken wat er niet goed gaat? Zou erg fijn zijn (want het werkt niet, de display werkt, maar reageert niet op de IR (NEC Data).
De 'case 4' in de interrupt routine heb ik maar even weg-gecommentarieerd omdat ik daar niets mee kan.

c code:

 '==============================================================================
Program IR_HD44780
'==============================================================================

dim LCD_RS as sbit at LATB3_bit
    LCD_EN as sbit at LATB2_bit
    LCD_D4 as sbit at LATA0_bit
    LCD_D5 as sbit at LATA1_bit
    LCD_D6 as sbit at LATA2_bit
    LCD_D7 as sbit at LATA3_bit

    LCD_RS_Direction as sbit at TRISB3_bit
    LCD_EN_Direction as sbit at TRISB2_bit
    LCD_D4_Direction as sbit at TRISA0_bit
    LCD_D5_Direction as sbit at TRISA1_bit
    LCD_D6_Direction as sbit at TRISA2_bit
    LCD_D7_Direction as sbit at TRISA3_bit

    nec_ok       As Bit
    text         As Char[5]
    Nec_state    As Integer
    Command1     As Integer
    Inv_command  As integer
    i            As Integer
    Address      As Integer
    Timer_Value  As integer
    Nec_code     As integer

'================================================================================
Sub procedure Interrupt() iv 0x0004 ics ICS_AUTO
'================================================================================

  If (IOCBF0 AND (PORTB.0 Xor 1)) then              ' PORTB change ISR
      IOCBF0_Bit = 0
    if(nec_state <> 0) then
      timer_value = (TMR1H << 8) + TMR1L            ' Store Timer1 value
      TMR1H = 0                                     ' Reset Timer1
      TMR1L = 0
    end if
    select case nec_state
     case 0                                        ' Start receiving IR data (we're at the beginning of 9ms pulse)
       TMR1H = 0                                   ' Reset Timer1
       TMR1L = 0
       TMR1ON_bit = 1                              ' Enable Timer1
       nec_state = 1                               ' Next state: end of 9ms pulse (start of 4.5ms space)
       i = 0
     case 1                                        ' End of 9ms pulse
       if((timer_value > 9500) OR (timer_value < 8500)) then          ' Invalid interval ==> stop decoding and reset
         nec_state = 0                             ' Reset decoding process
         TMR1ON_bit = 0                            ' Disable Timer1
       else
         nec_state = 2                             ' Next state: end of 4.5ms space (start of 562µs pulse)
        end if
     case 2                                        ' End of 4.5ms space
       if((timer_value > 5000) OR (timer_value < 4000))then
         nec_state = 0                             ' Reset decoding process
         TMR1ON_bit = 0                            ' Disable Timer1
       else
         nec_state = 3
       end if                                       ' Next state: end of 562µs pulse (start of 562µs or 1687µs space)
     case 3                                       ' End of 562µs pulse
       if((timer_value > 700) OR (timer_value < 400)) then           ' Invalid interval ==> stop decoding and reset
         TMR1ON_bit = 0                            ' Disable Timer1
         nec_state = 0                             ' Reset decoding process
       else
         nec_state = 4                             ' Next state: end of 562µs or 1687µs space
       end if

     case 4                                       ' End of 562µs or 1687µs space
      ' if((timer_value > 1800) OR (timer_value < 400))then  '           ' Time interval invalid ==> stop decoding
'         TMR1ON_bit = 0                            ' Disable Timer1
'         nec_state = 0                             ' Reset decoding process
'        End if
'       if( timer_value > 1000) then                     ' If space width > 1ms (short space)
'         If nec_code <> LongWord 1 << (31-i) Then       ' Write 1 to bit (31 - i)
'       else                                             ' If space width < 1ms (long space)
'        ' nec_code &= ~((unsigned long)1 << (31 - i));    ' Write 0 to bit (31 - i)
'          nec_code &= ~((unsigned long)1 << (31 - i));    ' Write 0 to bit (31 - i)
'       i = i + 1
''
'       if(i > 31) then                                  ' If all bits are received
'         nec_ok = 1                                 ' Decoding process OK
'         IOCBN0 = 0                                ' Disable PORTB change interrupt
'       End if
    '   End if
    case else                                       'Er zelf maar in gezet
       nec_state = 3                               ' Next state: end of 562µs pulse (start of 562µs or 1687µs space)
    End Select

    if (TMR1IF_bit) then            ' Timer1 ISR
      TMR1IF_bit = 0                ' Clear Timer1 overflow flag bit
      nec_state = 0                 ' Reset decoding process
      TMR1ON_bit = 0                ' Disable Timer1
    End if
  
 End if
 End Sub
 
'==============================================================================
main:
'==============================================================================
  ANSELB = 0                                    'All output/digital
  ANSELA = 0                                    '
  TRISA  = 0                                    '
  TRISB  = 0                                    '
  OSCCON = %01110000                            '8MHz internal
  TRISA = %11110000
  TRISB = %11111111
  nec_ok = 0
  nec_state = 0
  
  GIE_bit    = 1                                'Enable timer irq
  PEIE_bit   = 1                                '
  TMR1IE_bit = 1                                '

  TMR1IF_bit = 0                                'Clear Timer1 overflow interrupt flag bit
  IOCBF0_bit = 0                                'Clear PORTB change interrupt flag bit
  TMR1IE_bit = 1                                'Enable Timer1 overflow interrupt
  T1CON      = 0x10                             'Set Timer1 clock source to internal with 1:2 prescaler (Timer1 clock = 1MHz)
  INTCON     = 0xC8                             'Enable global, peripheral and PORTB change interrupts
  IOCBP0_Bit = 1                                'Enable RB0 pin change Interrupt

  
  Lcd_Init()                                    '
  Lcd_Cmd(_LCD_CLEAR)
  Lcd_Cmd(_LCD_CURSOR_OFF)
  
  Lcd_Out(1, 1, "Address:0x0000")
  Lcd_Out(2, 1, "Com:0x00 In:0x00")

While True
    while (Not nec_ok) Wend              ' Wait until NEC code receiver
    nec_ok = 0                          ' Reset decoding process
    nec_state = 0
    TMR1IE_bit =  0                     ' Disable Timer1
    address = nec_code >> 16
    command1 = nec_code >> 8
    inv_command = nec_code
    IntToHex(address, text)             ' Save address in string text with hex format
    Lcd_Out(1, 11, text)                ' Display address
    ByteToHex(command1, text)           ' Save command in string text with hex format
    Lcd_Out(2, 7, text)                 ' Display command
    ByteToHex(inv_command, text)        ' Save inverted command in string text with hex format
    Lcd_Out(2, 15, text)                ' Display inverted command
    IOCBP0_Bit = 1                      ' Enable PORTB change interrupt

Wend
                                  '
end. 
Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Ik ben zelf nog een tijd wezen rommelen met het programma.
En wat afgeleide andere programma's bekeken waar ik een interrupt gebruik.

Want het huidige programma zoals gepost rammelt ook.

Ook het omzetten van een Arduino-sketch naar MikroBasic is nagenoeg onmogelijk. Dat wil zeggen: voor mij. ;(

En om nou weer PicBasic te gaan installeren (omdat daar ook een voorbeeld van is) is ook weer een stap te ver (en in de tijd terug).

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Het zijn van die dagen dat niets meer lukt...

Zelfs een simpele tekst op een LCD met een PIC16F628A werkt niet meer...

Waarom werkt dit niet? (komt wel wat op scherm, maar alleen maar rare tekens)

pic basic code:

'==============================================================================
Program IR_HD44780
'==============================================================================
 
 Symbol LED_Geel     = PORTA.0
 Symbol LED_Rood     = PORTA.1
 Symbol LED_Groen    = PORTA.2
 Symbol LED_Toggle   = PORTA.3
 Symbol IR_Ontvanger = PORTA.4
'
 Dim LCD_RS as Sbit at PORTB.3
     LCD_EN as sbit at PORTB.2
     LCD_D4 as sbit at PORTB.7
     LCD_D5 as sbit at PORTB.6
     LCD_D6 as sbit at PORTB.5
     LCD_D7 as sbit at PORTB.4

    LCD_RS_Direction as sbit at TRISB.3
    LCD_EN_Direction as sbit at TRISB.2
    LCD_D4_Direction as sbit at TRISB.7
    LCD_D5_Direction as sbit at TRISB.6
    LCD_D6_Direction as sbit at TRISB.5
    LCD_D7_Direction as sbit at TRISB.4

'==============================================================================
main:

'==============================================================================
                 '
  CMCON  = 0x07                                ' Disable comparators   
  PCON.OSCF = 1                                ' 4MHz internal
  TRISA = %11110000
  TRISB = %11111111

  Lcd_Init()                                    '
  Lcd_Cmd(_LCD_CLEAR)
  Lcd_Cmd(_LCD_CURSOR_OFF)
  
  Lcd_Out(1, 1, "Regel-1")
  Lcd_Out(2, 1, "Regel-2")

While True

Wend
                                  '
end.
Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Waarom staat portb als inputs???

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

Golden Member

Op 8 november 2020 18:26:35 schreef Arco:
Waarom staat portb als inputs???

Dat stond in een voorbeeld (Uit de PICBasic cursus). Ik vond dat ook al vreemd, omdat de datalijnen van de LCD daar aan hangen.

Ik heb het gewijzigd in Output, maar resultaat blijft hetzelfde. Wat ik wel merk, Poort B 6 en 7 worden ook gebruikt voor de ISP.

Wanneer de schakeling aan gaat, staan er allemaal ? karakters op de LCD. Na het schrijven verschijnt er steeds een plukje onzin op de LCD.

De frequentie is goed, een testledje die ik met 1 sec laat knipperen werkt gewoon.

Rara..

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Met een PIC16F1847 werkt het overigens allemaal wel.

alleen LAT ipv Port

Met de PIC16F628A is onderstaand ook net iets anders dan bij de 1847:

pic basic code:

Dim LCD_RS as Sbit at PORTB.3
     LCD_EN as sbit at PORTB.2
     LCD_D4 as sbit at PORTB.7
     LCD_D5 as sbit at PORTB.6
     LCD_D6 as sbit at PORTB.5
     LCD_D7 as sbit at PORTB.4
Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Je moet ook niet de pickit aan de print laten hangen tijdens een run, dat gaat meestal mis...

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

Golden Member

Op 8 november 2020 18:52:41 schreef Arco:
Je moet ook niet de pickit aan de print laten hangen tijdens een run, dat gaat meestal mis...

Tot nu toe ging dat altijd goed.. ;)

Maar ik heb na het programmeren de PicKit er af gehaald en een 5V er aan gehangen voor de voeding.

Het effect: LCD toont wat anders, maar de ene rommel wordt vervangen door de andere.... ;(

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

In een oud voorbeeld gebruikte ik voor de LCD de Poorten A0 t/m A3. Kan ik ook nog wel eens proberen...Dan heb ik dat ISP gedoe ook niet.

Dit probleem is in ieder geval opgelost. Eerst PORTA genomen. Werkt.
Toen toch maar weer terug naar PORTB. Werkt ook...

Het zal aan het weer hebben gelegen. of aan de verkiezingen in de USA. Of - meer waarschijnlijk - ik had iets niet goed aangesloten...
:>

Nu maar eens verder met de IR. Ik probeer nu het voorbeeld uit de Picbasic cursus om te zetten naar Mikrobasic.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Nog een vraagje:

Waarom moet ik bij de interrupt flag bij een PIC16F1847 IOCBN.0 opgeven en niet IOCBN0?

Deze laatste zou ik af uit de datasheet

Maar dat pikt de compiler niet...

Fouten zijn het bewijs dat je het probeert..

Dit topic is gesloten