Laserwaterpas ontvanger

code:

#define MAX_INTERVAL 500 // max time a LED can be off while blinking, in ms
#define STABILITY_THRESHOLD 50 // time the input state must be stable before movement starts, in ms

#define DO_NOTHING  0x00
#define MOVE_UP   0x01
#define MOVE_DOWN 0x02
#define MOVE_FAST 0x04
#define MOVE_UPFAST (MOVE_UP | MOVE_FAST)
#define MOVE_DOWNFAST (MOVE_DOWN | MOVE_FAST)

// what to do for each combination of inputs; any combination of 2 or more active inputs means
// do nothing, only the combinations with exactly one active input, except the middle (neatral) input
// result in movement. These are positions 0x01 (1) for up fast, 0x02 (2) for up slow, 0x04 (4) for neutral,
// 0x08 (8) for down slow, 0x10 (16) for down fast. Note the array index starts at 0
const unsigned char Actions[ 32 ] = 
  { DO_NOTHING, MOVE_UPFAST, MOVE_UP, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, // 0..7
    MOVE_DOWN, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, // 8..15
    MOVE_DOWNFAST, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, // 16..23
    DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING }; // 24..31

unsigned short InputCounters[ 5 ] = { 0, 0, 0, 0, 0 };
unsigned char ReadInputs, FilteredInputs, PreviousInputs = 0;
unsigned long StabilityCount = 0;

void setup()
{
  pinMode( 0, INPUT ); // input top LED
  pinMode( 1, INPUT );
  pinMode( 2, INPUT );
  pinMode( 3, INPUT );
  pinMode( 4, INPUT ); // input bottom LED
  pinMode( 5, OUTPUT ); // move UP output
  pinMode( 6, OUTPUT ); // move DOWN output
  pinMode( 7, OUTPUT ); // move FAST output
}

void loop()
{
  unsigned char Index;
  
  FilteredInputs = 0;
  ReadInputs = digitalRead( 0 ) | ( digitalRead( 1 ) << 1 ) | ( digitalRead( 2 ) << 2 ) | ( digitalRead( 3 ) << 3 ) | ( digitalRead( 4 ) << 4 );

  // this loop monitors each input for recent activity; when an input is active, the timer for that inputs
  // is set to MAX_INTERVAL, and starts counting down from there; when it reaches 0, the input is considered
  // inactive. MAX_INTERVAL should be set slightly longer than the maximum time the LED for an input can be off
  // when blinking
  for( Index = 0; Index < 5; Index++ )
  {
    if( ReadInputs & ( 1 << Index ) )
      InputCounters[ Index ] = MAX_INTERVAL;

    if( InputCounters[ Index ] )
    {
      InputCounters[ Index ]--;
      FilteredInputs |= 1 << Index;
    }
  }

  // now check if the input state has been stable for a number of successive cycles, to prevent movement
  // when 2 LEDs are blinking, since one can always be detected slightly earlier or later than the other
  // If current and previous input states are different, reset stability counter
  if( PreviousInputs != FilteredInputs )
    StabilityCount = 0;

  // now store the current input state for the next cycle
  PreviousInputs = FilteredInputs;

  // if stability counter has not yet reached the threshold, increment it, and force the input state to 0
  // to prevent any movement
  if( StabilityCount < STABILITY_THRESHOLD )
  {
    StabilityCount++;
    FilteredInputs = 0;
  }

  // lookup what to do for this state and write to outputs
  digitalWrite( 5, Actions[ FilteredInputs ] & MOVE_UP );
  digitalWrite( 6, Actions[ FilteredInputs ] & MOVE_DOWN );
  digitalWrite( 7, Actions[ FilteredInputs ] & MOVE_FAST );

  delay(1); // actual loop interval will be slightly longer, because it also takes some time to execute
}

Niet getest, bij gebrek aan hardware. Misschien dat ik het later nog in een simulatie omgeving ga testen.

Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken
Lambiek

Special Member

Op 6 september 2020 11:35:25 schreef SparkyGSX:
Niet getest, bij gebrek aan hardware. Misschien dat ik het later nog in een simulatie omgeving ga testen.

Kijk daar heeft de TS iets aan. _/-\o_

En maak alstublieft niet meer van die denigrerende opmerkingen, je kunt nu eenmaal geen goed programma maken als je het niet kunt testen of de hardware niet hebt. En ik heb hier geen simulatie programma of iets dergelijks.

Want hier "Een goede programmeur had nog een one-hot detectie toegevoegd, om raar gedag te voorkomen als er onverhoopt meer dan één sensor actief wordt" trap je iemand mee op zijn ziel.

We proberen allemaal te helpen en met zulke opmerkingen schiet niemand iets op, maar dat geld ook voor mij uiteraard.

En verder heb ik je hoog staan, dat weet je.

Ik had ook nog een poging gedaan, naar de nieuwe data van de TS.

AANGEPAST PROGRAMMA.

pic basic code:


Device 16F887                               ; Processor type

Xtal 10                                     ; Cristal 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                            

Symbol NIVEAU_BOVEN_1 = PORTA.0             ; Ingang
Symbol NIVEAU_BOVEN_2 = PORTA.1             ; Ingang
Symbol NIVEAU_NUL     = PORTA.2             ; Ingang
Symbol NIVEAU_ONDER_1 = PORTA.3             ; Ingang
Symbol NIVEAU_ONDER_2 = PORTA.5             ; Ingang
Symbol RESET_DUBBEL   = PORTE.0             ; Ingang

Symbol VENTIEL_A = PORTC.0                  ; Uitgang relais
Symbol VENTIEL_B = PORTC.1                  ; Uitgang relais
Symbol VENTIEL_C = PORTC.2                  ; Uitgang relais
Symbol VENTIEL_D = PORTC.3                  ; Uitgang relais

Symbol LED_NIVEAU_BOVEN_1 = PORTB.0         ; Uitgang controle led
Symbol LED_NIVEAU_BOVEN_2 = PORTB.1         ; Uitgang controle led
Symbol LED_NIVEAU_NUL     = PORTB.2         ; Uitgang controle led
Symbol LED_NIVEAU_ONDER_1 = PORTB.3         ; Uitgang controle led
Symbol LED_NIVEAU_ONDER_2 = PORTB.4         ; Uitgang controle led

Symbol ALARM_GEEN_DETECTIE  = PORTC.4       ; Uitgang alarm
Symbol ALARM_DUBBEL_SIGNAAL = PORTC.5       ; Uitgang alarm

Dim BIT_1 As Bit                            ; Detectie bit
Dim BIT_2 As Bit                            ; Detectie bit

DelayMS 1000                                ; Pauze 1 sec 

Clear                                       ; Wis geheugen

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

         ;543210                            ; Hulpregel poort B
PORTB  = %000000                            ; Maak poort B laag
TRISB  = %000000                            ; 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  = %111                               ; 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

;----------------------------------------
; ZET UITGANGEN EN BIT_1 EN BIT_2 OP NUL.
;----------------------------------------

ALARM_GEEN_DETECTIE  = 0
ALARM_DUBBEL_SIGNAAL = 0

LED_NIVEAU_BOVEN_1 = 0
LED_NIVEAU_BOVEN_2 = 0
LED_NIVEAU_NUL     = 0
LED_NIVEAU_ONDER_1 = 0
LED_NIVEAU_ONDER_2 = 0

VENTIEL_A = 0
VENTIEL_B = 0
VENTIEL_C = 0
VENTIEL_D = 0

BIT_1 = 0
BIT_2 = 0

;-----------------------------------------------------------------
; AFVRAGEN LEDS OP DE LASER ONTVANGER EN INLEZEN IN DE CONTROLLER.
;-----------------------------------------------------------------

RUN:


    ALARM_GEEN_DETECTIE  = 0
    ALARM_DUBBEL_SIGNAAL = 0

    LED_NIVEAU_BOVEN_1 = 0
    LED_NIVEAU_BOVEN_2 = 0
    LED_NIVEAU_ONDER_1 = 0
    LED_NIVEAU_ONDER_2 = 0

    VENTIEL_A = 0
    VENTIEL_B = 0
    VENTIEL_C = 0
    VENTIEL_D = 0
    
    BIT_1 = 0
    BIT_2 = 0

    If NIVEAU_BOVEN_2 = 1 Then BIT_1 = 1  
     
    If NIVEAU_ONDER_2 = 1 Then BIT_2 = 1
    
    If BIT_1 = 1 And BIT_2 = 1 Then
       GoTo GEEN_DETECTIE
    EndIf
    
    If NIVEAU_NUL = 1 Then 
       LED_NIVEAU_NUL = 1 
       GoTo RUN
    EndIf
    
    If NIVEAU_BOVEN_1 = 1 Then
       GoSub SCHUIF_GEREDUCEERD_OMHOOG
    EndIf
    
    If NIVEAU_BOVEN_2 = 1 Then
       GoSub SCHUIF_OMHOOG
    EndIf
    
    If NIVEAU_ONDER_1 = 1 Then
       GoSub SCHUIF_GEREDUCEERD_OMLAAG
    EndIf
    
    If NIVEAU_ONDER_2 = 1 Then
       GoSub SCHUIF_OMLAAG
    EndIf
       
GoTo RUN

;------------------------------------------------------
; GEREDUCEERDE REACTIE OP NIVEAU_BOVEN_1.
; VENTIE_A BLIJFT ACTIEF TOTDAT NIVEAU_NUL BEREIKT IS.
; OF TOTDAT EEN ANDER NIVEAU BEREIKT IS.
; OF TOTDAT DE LASER ER UIT LOOPT OF BUITEN BEREIK IS.
;------------------------------------------------------
    
SCHUIF_GEREDUCEERD_OMHOOG:


    LED_NIVEAU_BOVEN_1 = 1
    LED_NIVEAU_BOVEN_2 = 0
    LED_NIVEAU_NUL     = 0
    LED_NIVEAU_ONDER_1 = 0
    LED_NIVEAU_ONDER_2 = 0

    VENTIEL_A = 1
    VENTIEL_B = 0
    VENTIEL_C = 0
    VENTIEL_D = 0
    
    BIT_1 = 0
    BIT_2 = 0

    If NIVEAU_NUL = 1 Then
       VENTIEL_A = 0
        DelayMS 100
       Return
    EndIf
    
    If NIVEAU_BOVEN_2 = 1 Then BIT_1 = 1  
     
    If NIVEAU_ONDER_2 = 1 Then BIT_2 = 1
    
    If BIT_1 = 1 And BIT_2 = 1 Then
       GoTo GEEN_DETECTIE
    EndIf
    
    If NIVEAU_NUL = 1 And NIVEAU_BOVEN_1 = 1 Then
       GoTo DUBBEL_SIGNAAL
    EndIf
    
    If NIVEAU_BOVEN_1 = 1 And NIVEAU_BOVEN_2 = 1 Then
       GoTo DUBBEL_SIGNAAL
    EndIf
    
    If NIVEAU_BOVEN_2 = 1 Then
       Return
    EndIf
    
    If NIVEAU_ONDER_1 = 1 Then
       Return
    EndIf
    
    If NIVEAU_ONDER_2 = 1 Then
       Return
    EndIf
    
GoTo SCHUIF_GEREDUCEERD_OMHOOG

;------------------------------------------------------
; REACTIE OP NIVEAU_BOVEN_2.
; VENTIE_C BLIJFT ACTIEF TOTDAT NIVEAU_NUL BEREIKT IS.
; OF TOTDAT EEN ANDER NIVEAU BEREIKT IS.
; OF TOTDAT DE LASER ER UIT LOOPT OF BUITEN BEREIK IS.
;------------------------------------------------------

SCHUIF_OMHOOG:


    LED_NIVEAU_BOVEN_1 = 0
    LED_NIVEAU_BOVEN_2 = 1
    LED_NIVEAU_NUL     = 0
    LED_NIVEAU_ONDER_1 = 0
    LED_NIVEAU_ONDER_2 = 0

    VENTIEL_A = 0
    VENTIEL_B = 0
    VENTIEL_C = 1
    VENTIEL_D = 0
    
    BIT_1 = 0
    BIT_2 = 0
    
    If NIVEAU_NUL = 1 Then
       VENTIEL_C = 0
        DelayMS 100
       Return
    EndIf
    
    If NIVEAU_BOVEN_2 = 1 Then BIT_1 = 1
     
    If NIVEAU_ONDER_2 = 1 Then BIT_2 = 1
    
    If BIT_1 = 1 And BIT_2 = 1 Then
       GoTo GEEN_DETECTIE
    EndIf
    
    If NIVEAU_BOVEN_2 = 1 And NIVEAU_BOVEN_1 = 1 Then
       GoTo DUBBEL_SIGNAAL
    EndIf
    
    If NIVEAU_BOVEN_1 = 1 And NIVEAU_NUL = 1 Then
       GoTo DUBBEL_SIGNAAL
    EndIf
    
    If NIVEAU_BOVEN_1 = 1 Then
       Return
    EndIf
    
    If NIVEAU_ONDER_1 = 1 Then
       Return
    EndIf
    
    If NIVEAU_ONDER_2 = 1 Then
       Return
    EndIf
    
GoTo SCHUIF_OMHOOG

;------------------------------------------------------
; GEREDUCEERDE REACTIE OP NIVEAU_ONDER_1.
; VENTIE_B BLIJFT ACTIEF TOTDAT NIVEAU_NUL BEREIKT IS.
; OF TOTDAT EEN ANDER NIVEAU BEREIKT IS.
; OF TOTDAT DE LASER ER UIT LOOPT OF BUITEN BEREIK IS.
;------------------------------------------------------

SCHUIF_GEREDUCEERD_OMLAAG:


    LED_NIVEAU_BOVEN_1 = 0
    LED_NIVEAU_BOVEN_2 = 0
    LED_NIVEAU_NUL     = 0
    LED_NIVEAU_ONDER_1 = 1
    LED_NIVEAU_ONDER_2 = 0

    VENTIEL_A = 0
    VENTIEL_B = 1
    VENTIEL_C = 0
    VENTIEL_D = 0
    
    BIT_1 = 0
    BIT_2 = 0
    
    If NIVEAU_NUL = 1 Then
       VENTIEL_B = 0
        DelayMS 100
       Return
    EndIf
    
    If NIVEAU_BOVEN_2 = 1 Then BIT_1 = 1  
     
    If NIVEAU_ONDER_2 = 1 Then BIT_2 = 1
    
    If BIT_1 = 1 And BIT_2 = 1 Then
       GoTo GEEN_DETECTIE
    EndIf
    
    If NIVEAU_NUL = 1 And NIVEAU_ONDER_1 = 1 Then
       GoTo DUBBEL_SIGNAAL
    EndIf
    
    If NIVEAU_ONDER_1 = 1 And NIVEAU_ONDER_2 = 1 Then
       GoTo DUBBEL_SIGNAAL
    EndIf
    
    If NIVEAU_BOVEN_1 = 1 Then
       Return
    EndIf
    
    If NIVEAU_BOVEN_2 = 1 Then
       Return
    EndIf
    
    If NIVEAU_ONDER_2 = 1 Then
       Return
    EndIf
    
GoTo SCHUIF_GEREDUCEERD_OMLAAG

;------------------------------------------------------
; REACTIE OP NIVEAU_ONDER_2.
; VENTIE_D BLIJFT ACTIEF TOTDAT NIVEAU_NUL BEREIKT IS.
; OF TOTDAT EEN ANDER NIVEAU BEREIKT IS.
; OF TOTDAT DE LASER ER UIT LOOPT OF BUITEN BEREIK IS.
;------------------------------------------------------
  
SCHUIF_OMLAAG:


    LED_NIVEAU_BOVEN_1 = 0
    LED_NIVEAU_BOVEN_2 = 0
    LED_NIVEAU_NUL     = 0
    LED_NIVEAU_ONDER_1 = 0
    LED_NIVEAU_ONDER_2 = 1

    VENTIEL_A = 0
    VENTIEL_B = 0
    VENTIEL_C = 0
    VENTIEL_D = 1
    
    BIT_1 = 0
    BIT_2 = 0
    
    If NIVEAU_NUL = 1 Then
       VENTIEL_D = 0
        DelayMS 100
       Return
    EndIf
    
    If NIVEAU_BOVEN_2 = 1 Then BIT_1 = 1
     
    If NIVEAU_ONDER_2 = 1 Then BIT_2 = 1
    
    If BIT_1 = 1 And BIT_2 = 1 Then
       GoTo GEEN_DETECTIE
    EndIf
    
    If NIVEAU_ONDER_2 = 1 And NIVEAU_ONDER_1 = 1 Then
       GoTo DUBBEL_SIGNAAL
    EndIf
    
    If NIVEAU_ONDER_1 = 1 And NIVEAU_NUL = 1 Then
       GoTo DUBBEL_SIGNAAL
    EndIf
    
    If NIVEAU_BOVEN_1 = 1 Then
       Return
    EndIf
    
    If NIVEAU_BOVEN_2 = 1 Then
       Return
    EndIf
    
    If NIVEAU_ONDER_1 = 1 Then
       Return
    EndIf
    
GoTo SCHUIF_OMLAAG

;------------------------------------------------
; LASER ER UIT GELOPEN OF BUITEN BEREIK
; RESET DOOR HANDMATIG NAAR NIVEAU_NUL TE STUREN.
;------------------------------------------------

GEEN_DETECTIE:


    ALARM_GEEN_DETECTIE  = 1
    
    LED_NIVEAU_BOVEN_1 = 0
    LED_NIVEAU_BOVEN_2 = 0
    LED_NIVEAU_NUL     = 0
    LED_NIVEAU_ONDER_1 = 0
    LED_NIVEAU_ONDER_2 = 0

    VENTIEL_A = 0
    VENTIEL_B = 0
    VENTIEL_C = 0
    VENTIEL_D = 0
      
    If NIVEAU_NUL = 1 Then
       BIT_1 = 0
       BIT_2 = 0
       DelayMS 100
       GoTo RUN
    EndIf
            
GoTo GEEN_DETECTIE

DUBBEL_SIGNAAL:


    ALARM_DUBBEL_SIGNAAL = 1
    
    LED_NIVEAU_BOVEN_1 = 0
    LED_NIVEAU_BOVEN_2 = 0
    LED_NIVEAU_NUL     = 0
    LED_NIVEAU_ONDER_1 = 0
    LED_NIVEAU_ONDER_2 = 0

    VENTIEL_A = 0
    VENTIEL_B = 0
    VENTIEL_C = 0
    VENTIEL_D = 0
    
    BIT_1 = 0
    BIT_2 = 0
    
    If RESET_DUBBEL = 1 Then
       DelayMS 500
       GoTo RUN
    EndIf
GoTo DUBBEL_SIGNAAL

End
Als je haar maar goed zit, GROETEN LAMBIEK.

Op 6 september 2020 10:41:06 schreef hennep:
[...]
Ben je nu aan het beweren dat HvZ niet ontzettend technisch is? :) :+

Allicht technischer dan ik! In ieder geval op dit gebied. ;)

@SparyGSX, vele malen dank! Als het me qua tijd lukt ga ik morgen proberen een opzetje te maken en testen met jouw programma in de Arduino. Als ik rare dingen tegen kom laat ik het zeker weten!

@Lambiek, nogmaals bedankt voor jouw input. Helaas is dit wat lastiger te testen omdat ik hem eerst naar de Arduino code om moet zetten en dat is voor mij niet "even tikwerk".

Lambiek

Special Member

Op 6 september 2020 17:49:53 schreef BartL:
@Lambiek, nogmaals bedankt voor jouw input. Helaas is dit wat lastiger te testen omdat ik hem eerst naar de Arduino code om moet zetten en dat is voor mij niet "even tikwerk".

Maakt niet uit, Sparky heeft ook een code gemaakt, dus als dat voor jou beter uitkomt prima. :)

Wil het trouwens lukken met je foto transistor?

Als je haar maar goed zit, GROETEN LAMBIEK.

@Lambiek: Je hebt exact 0 van de problemen die ik heb benoemd opgelost.

- Je gaat er nog steeds vanuit dat de detectie van "geen ontvangst", waarbij de bovenste en onderste LED tegelijk knipperen, perfect tegelijk binnenkomt op je microcontroller. Wat gebeurd er als één van die twee een fractie van een seconde eerder komt? Niet alleen ga je dan onterecht naar een staat waar je snel omhoog of omlaag gaat sturen, maar je komt daar ook nooit meer uit, omdat je enkel nog kijkt naar de middelste LED. Als je nou op zijn minst in elk van de staten de "geen contact" situatie zou detecteren, zou je daar zo kort zijn dat je het waarschijnlijk niet eens zou merken. Niet netjes, maar wel functioneel.

- Afgezien van bovenstaande, kun je nu alleen in situatie "GEEN_DTECTIE" komen vanuit de neutrale positie; als je in willekeurig welke van de andere situaties zit, detecteer je dat nooit.

- Hoe zou je ooit in de staat "SCHUIF_OMHOOG" moeten komen? Immers, je gaat eerst naar "SCHUIF_GEREDUCEERD_OMHOOG", en de enige manier om daar weer uit te komen is als "NIVEAU_NUL" detecteerd wordt.

- Je hebt nog steeds geen bewaking toegevoegd voor de situatie dat je door een hardware fout of andere onvoorziene situatie meerdere ingangen tegelijk actief ziet.

Één van de grote oorzaken van al deze problemen is dat je de plaats in het programma gebruikt als state voor een state machine; dat betekend dat je op meerdere plaatsen, in elk van de states, moet gaan detecteren of alles in orde is. Als je nou in plaats daarvan een variabele gebruikt om de state op te slaan, kun je die detectie op één centrale plaats doen, en actie ondernemen, onafhankelijk van de staat waar je in zat.

Voor mij is de eerste stap bij het oplossing van een dergelijk probleem het stellen van de vraag: "wat kan hier allemaal fout gaan?". Dat is hier dus om te beginnen geen enkele LED detectie (voor langere tijd), detectie van meerdere ingangen tegelijk, instabiele detectie van ingangen, en verschillen in looptijd bij de "geen ontvangst" detectie. Jij doet ook nog eens de aanname dat situaties elkaar in een specifieke volgorde opvolgen, en dat kan dan ook nog fout gaan.

Vervolgens ga je nadenken over hoe je dat fundamenteel kunt oplossen; de situatie dat alles perfect gaat is triviaal, het is het correct reageren op alles wat fout kan gaan wat het verschil maakt dus een goed en een slecht stuk software.

@TS: wat voor Arduino wil je gebruiken? Misschien is het handig om er nog een paar LEDs aan te maken, waarmee de software kan aangeven wat de interne situatie is; wat is er gedetecteerd, en of die detectie stabiel is. Afhankelijk het type Arduino heb je daar meer of minder pinnen voor beschikbaar.

Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken

Op 6 september 2020 18:06:22 schreef Lambiek:
[...]
Wil het trouwens lukken met je foto transistor?

Net even een test opzetje gemaakt, maar ik krijg hem helaas nog niet werkend. Als ik hem analoog uitlees krijg ik een constante waarde van 14 die niet veranderd als ik de fototransistor donker maak oid.

Op 6 september 2020 22:52:12 schreef SparkyGSX:
@TS: wat voor Arduino wil je gebruiken? Misschien is het handig om er nog een paar LEDs aan te maken, waarmee de software kan aangeven wat de interne situatie is; wat is er gedetecteerd, en of die detectie stabiel is. Afhankelijk het type Arduino heb je daar meer of minder pinnen voor beschikbaar.

Mijn bedoeling was een Uno, deze heb ik namelijk liggen.

Lambiek

Special Member

Op 6 september 2020 22:52:12 schreef SparkyGSX:
- Hoe zou je ooit in de staat "SCHUIF_OMHOOG" moeten komen? Immers, je gaat eerst naar "SCHUIF_GEREDUCEERD_OMHOOG", en de enige manier om daar weer uit te komen is als "NIVEAU_NUL" detecteerd wordt.

- Je hebt nog steeds geen bewaking toegevoegd voor de situatie dat je door een hardware fout of andere onvoorziene situatie meerdere ingangen tegelijk actief ziet.

Ja, daar heb je gelijk in. Ik ben alleen uitgegaan van het grafiekje van de TS.
Het is ook nog niet klaar.

Ik laat het verder aan jou over.

Op 7 september 2020 08:38:29 schreef BartL:
Net even een test opzetje gemaakt, maar ik krijg hem helaas nog niet werkend. Als ik hem analoog uitlees krijg ik een constante waarde van 14 die niet veranderd als ik de fototransistor donker maak oid.

Je kunt nog een beetje met de weerstand waardes spelen.

En heb je toevallig een TLV271 liggen of een andere rail to rail opamp? Dan kun je het voorbeeld met de opamp schakeling maken.

Als je haar maar goed zit, GROETEN LAMBIEK.

Op 7 september 2020 09:15:56 schreef Lambiek:
Je kunt nog een beetje met de weerstand waardes spelen.

Dat kan ik wel doen, maar ook met een verkeerde weerstandswaarde zou hij toch wel iets moeten fluctueren bij het uitlezen zou ik denken...

Op 7 september 2020 09:15:56 schreef Lambiek:
En heb je toevallig een TLV271 liggen of een andere rail to rail opamp? Dan kun je het voorbeeld met de opamp schakeling maken.

Nee helaas, mijn voorraad is niet zo uitgebreid.

Ik vind die 1k weerstand linksboven (in serie met de fototransistor) wel erg klein; ik denk dat de stroom door de fototransistor niet groot genoeg wordt om daar 0.7V over te laten vallen, en bij gevolg gaat de transistor nooit in geleiding, en blijf je dus ongeveer 0V meten op de uitgang.

Ik zou die weerstand veel groter maken, 47-100k of zo.

Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken

Op 7 september 2020 10:23:07 schreef SparkyGSX:
Ik zou die weerstand veel groter maken, 47-100k of zo.

Beide geprobeerd maar zonder verandering hij blijft een waarde van 14 (0V) uitlezen.

Lambiek

Special Member

Heb je de foto transistor goed aangesloten? Heb je op het vlakke kantje gelet?

Wat voor kleur led gebruik je voor de test? Wat gebeurt er als je er met een zaklamp op schijnt? Als er licht op valt zou er iets moeten gebeuren lijkt mij. Transistor zit ook goed?

Ben je in het bezit van een scoop?

Lees je hem analoog in? Als dat zo is dan is de waarde 14 geen 0V.

Als je haar maar goed zit, GROETEN LAMBIEK.

Excuus, mijn fout. Ik deed iets verkeerd in het uitlezen in de Arduino. Nu werkt hij keurig. Ik krijg een waarde van ca.1000 bij de TL-verlichting en 0 als ik hem afdek.

Lambiek

Special Member

Op 7 september 2020 11:39:43 schreef BartL:
Excuus, mijn fout. Ik deed iets verkeerd in het uitlezen in de Arduino. Nu werkt hij keurig. Ik krijg een waarde van ca.1000 bij de TL-verlichting en 0 als ik hem afdek.

Maakt niet uit, het werkt nu.

Maak die weerstand boven de foto transistor niet al te groot, anders heb je kans dat het te gevoelig wordt.

Als je haar maar goed zit, GROETEN LAMBIEK.

Hou er rekening mee dat zijn (IR) fototransistor pt333 onder de 700nm bijna niks meer ziet, de bandbreedte gaat van ~700 tot 1100nm, terwijl een gemiddelde rode led rond de 630nm zit.

LDmicro user.
Lambiek

Special Member

Op 7 september 2020 12:27:48 schreef MGP:
Hou er rekening mee dat zijn (IR) fototransistor pt333 onder de 700nm bijna niks meer ziet, de bandbreedte gaat van ~700 tot 1100nm, terwijl een gemiddelde rode led rond de 630nm zit.

Daarom had ik ook de SFH305-2 uitgezocht, daar loopt de bandbreedte van 440 tot 1100.

En ik weet de kleuren van de leds niet in de ontvanger.

Als je haar maar goed zit, GROETEN LAMBIEK.

Op 7 september 2020 12:27:48 schreef MGP:
Hou er rekening mee dat zijn (IR) fototransistor pt333 onder de 700nm bijna niks meer ziet, de bandbreedte gaat van ~700 tot 1100nm, terwijl een gemiddelde rode led rond de 630nm zit.

Volgens de specs zit de bandbreedte van deze fototranstor op 400-1100nm.

Dat is juist, ik had het over een PT333-3C en de uwe zou dus een PT331C zijn alhoewel ze in de link schrijven dat een PT331C = PT333-3C.

LDmicro user.
Lambiek

Special Member

Als je haar maar goed zit, GROETEN LAMBIEK.

Ok, ik heb zojuist een test gedaan met het schema zoals door Lambiek beschreven alleen met een 47k weerstand in serie met de fototransistor. Dit reageert prima op de LED's van de ontvanger. Met een simpel programmaatje kan ik de LED's op de ontvanger door de Arduino laten kopieren op mijn breadboard.

@SparyGXS,
Ik heb jouw code ingeladen in de Arduino en wilde dit dmv Input1 en Output5 eens testen maar krijg geen output (als ik het goed lees zou Input1 Output5 moeten schakelen). Ik heb natuurlijk maar zeer gelimiteerde kennis mbt de code maar ik kan nergens echt terugvinden dat de output HIGH geschakeld dient te worden. Klopt dit?
EDIT: Ik zie nu net dat wanneer ik de input LOW houd (door mijn hand op de fototransistor te plaatsen) de output5 gaat knipperen...

@Lambiek,
Ik heb deze relais nog liggen, ik dacht het eigenlijk daarmee te doen.

Lambiek

Special Member

Op 7 september 2020 16:12:52 schreef BartL:
Ik heb deze relais nog liggen, ik dacht het eigenlijk daarmee te doen.

Ja, dat kan. Dan kun je het schema gebruiken.

Ik zou wel een aparte 5VDC gebruiken voor de voeding van de relais, dus niet de voeding uit je Arduino halen.

Als je haar maar goed zit, GROETEN LAMBIEK.

Ik heb nog wat kleine aanpassingen gedaan:
De StabilityCounter liep van 0 tot zijn limiet, terwijl de InputCounters precies andersom gingen; beide zijn geldige oplossingen, maar het is een beetje onlogisch om dit verschillend te doen, dus ik heb StabilityCounter aangepast.

De analoge pinnen worden niet analoog gebruikt, maar voor 6 LEDs die de interne status weergeven; A0 t/m A4 geven de status van de ingangen na het filter, terwijl A5 weergeeft of de status stabiel is bevonden. Elk van deze pinnen moet daarvoor een LED krijgen met een weerstand in serie, van de uitgang naar de ground voeding.

code:


#define MAX_INTERVAL 500 // max time a LED can be off while blinking, in ms
#define STABILITY_THRESHOLD 50 // time the input state must be stable before movement starts, in ms

#define DO_NOTHING  0x00
#define MOVE_UP   0x01
#define MOVE_DOWN 0x02
#define MOVE_FAST 0x04
#define MOVE_UPFAST (MOVE_UP | MOVE_FAST)
#define MOVE_DOWNFAST (MOVE_DOWN | MOVE_FAST)

// what to do for each combination of inputs; any combination of 2 or more active inputs means
// do nothing, only the combinations with exactly one active input, except the middle (neatral) input
// result in movement. These are positions 0x01 (1) for up fast, 0x02 (2) for up slow, 0x04 (4) for neutral,
// 0x08 (8) for down slow, 0x10 (16) for down fast. Note the array index starts at 0
const unsigned char Actions[ 32 ] = 
  { DO_NOTHING, MOVE_UPFAST, MOVE_UP, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, // 0..7
    MOVE_DOWN, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, // 8..15
    MOVE_DOWNFAST, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, // 16..23
    DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING, DO_NOTHING }; // 24..31

unsigned short InputCounters[ 5 ] = { 0, 0, 0, 0, 0 };
unsigned char ReadInputs, FilteredInputs, PreviousInputs = 0;
unsigned long StabilityCount = 0;

void setup()
{
  pinMode( 0, INPUT ); // input top LED
  pinMode( 1, INPUT );
  pinMode( 2, INPUT );
  pinMode( 3, INPUT );
  pinMode( 4, INPUT ); // input bottom LED
  pinMode( 5, OUTPUT ); // move UP output
  pinMode( 6, OUTPUT ); // move DOWN output
  pinMode( 7, OUTPUT ); // move FAST output

  pinMode( A0, OUTPUT ); // Debugging status LEDs
  pinMode( A1, OUTPUT );
  pinMode( A2, OUTPUT );
  pinMode( A3, OUTPUT );
  pinMode( A4, OUTPUT );
  pinMode( A5, OUTPUT );
}

void loop()
{
  unsigned char Index;
  
  FilteredInputs = 0;
  ReadInputs = digitalRead( 0 ) | ( digitalRead( 1 ) << 1 ) | ( digitalRead( 2 ) << 2 ) | ( digitalRead( 3 ) << 3 ) | ( digitalRead( 4 ) << 4 );

  // this loop monitors each input for recent activity; when an input is active, the timer for that inputs
  // is set to MAX_INTERVAL, and starts counting down from there; when it reaches 0, the input is considered
  // inactive. MAX_INTERVAL should be set slightly longer than the maximum time the LED for an input can be off
  // when blinking
  for( Index = 0; Index < 5; Index++ )
  {
    if( ReadInputs & ( 1 << Index ) )
      InputCounters[ Index ] = MAX_INTERVAL;

    if( InputCounters[ Index ] )
    {
      InputCounters[ Index ]--;
      FilteredInputs |= 1 << Index;
    }

    // write each input filter status to a debug LED (A0 + 3 is the same as A3)
    digitalWrite( A0 + Index, !InputCounters[ Index ] );
  }

  // now check if the input state has been stable for a number of successive cycles, to prevent movement
  // when 2 LEDs are blinking, since one can always be detected slightly earlier or later than the other
  // If current and previous input states are different, reset stability counter
  if( PreviousInputs != FilteredInputs )
    StabilityCount = STABILITY_THRESHOLD;

  // now store the current input state for the next cycle
  PreviousInputs = FilteredInputs;

  // if stability counter has not yet reached the threshold, increment it, and force the input state to 0
  // to prevent any movement
  if( StabilityCount )
  {
    StabilityCount--;
    FilteredInputs = 0;
  }

  // write Stability status to debug LED
  digitalWrite( A5, !StabilityCount );
  
  // lookup what to do for this state and write to outputs
  digitalWrite( 5, Actions[ FilteredInputs ] & MOVE_UP );
  digitalWrite( 6, Actions[ FilteredInputs ] & MOVE_DOWN );
  digitalWrite( 7, Actions[ FilteredInputs ] & MOVE_FAST );

  delay(1); // actual loop interval will be slightly longer, because it also takes some time to execute
}
Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken

Op 7 september 2020 20:39:55 schreef SparkyGSX:
Ik heb nog wat kleine aanpassingen gedaan:

En is hiermee de bug die ik eerder aangaf ook verwijderd? En hoe zit het met de output signalen die ik niet echt terug kan vinden?

Ik had je eerdere bericht gemist. Ik kan het gedrag niet direct plaatsen; voor de normale werking gebruikt de code D0..D4 als ingangen en D5..D7 als uitgangen; pin A0..A5 zijn voor de debug LEDs.

Weet je zeker dat je de juiste in- en uitgangen gebruikt? Wat is de knipper frequentie ongeveer, of is die onregelmatig?

Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken

Ik heb alleen pin 1 en 5 aangesloten. Op pin 5 een ledje om de output te controleren. Deze knippert dus wanneer de input LOW is. Knipperen is ca. 1sec aan/ 1sec uit.

Eh, je moet de andere ingangen wel met weerstandjes omlaag trekken, anders gaan die zweven, en dat zijn ongeldige combinaties.

Helaas heeft de Arduino alleen pull-ups die je kunt aanzetten, geen pull-downs, anders had ik dat wel gedaan.

Als je A0 t/m A5 een LED geeft, kun je wat beter zien wat de interne status is. Als A5 hoog blijft (LED uit; de LEDs moeten van de uitgang naar de voeding) is de status van de ingangen niet stabiel.

[Bericht gewijzigd door SparkyGSX op 7 september 2020 22:43:05 (30%)]

Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken