robot look like johnny 5 (leuk project)

"NEED INPUT" ;)

Eindelijk wat vorderingen w.b. picbasic!
Een lcd aansturen met een 16f628 ging probleemloos, maar op een 16F877 liep ik al meteen tegen een veelvoorkomend probleem op, n.l. de eerste rij met allemaal zwarte blokjes.
Dat ik niet de enige was bleek wel uit de vele hits op de zoekmachine naar dit probleem
Het was een probleem in de config regel.
Nu dit werkte heb ik mijn SRF05 aangesloten, en met veel experimenteren en na +/- 200 ERRORS in proton heb ik het nu voor elkaar.
Hij meet mooi de afstand, en zet dit op mijn LCD.
nu komt de volgende vraag, waar ikzelf zo niet uit kom:
Ik wil een poort hoog maken als als de gemeten waarde binnen bv. 50cm komt.
Picbasic.nl werkt alleen maar met het commando POT
En iets anders kon ik met Google niet vinden
moet ik hiervoor ADIN of RCIN voor gebruiken? en hoe?
DE code zover ik nu ben:

pic basic code:

Device 16F877
Config hs_osc,wdt_off,pwrte_on,BODEN_On,LVP_OFF
 XTAL 4  
 
Dim afstand As Word
Dim zendpuls As Word
Dim echo As Word

Symbol pulsuit = PORTD.2
Symbol ontvang = PORTD.3
DelayMS 500
Cls

While 1 = 1
 
PulsOut pulsuit, 1                  ; zend puls
DelayUS 40                          ; wacht op echo
afstand = PulsIn ontvang,1   
DelayUS 40                          ; ontvant de echo
Print At 1, 1, Dec afstand /58      ; zet waarde op lcd

 Wend
End

Lucky Luke schreef: Als je de sensor met een servo kunt laten ronddraaien kun je kijken bij welke servopositie de sensor de grootste afstand meet. Daar zit dan de vrije doorgang. Vervolgens stuur je je robot die richting op (eerst bijdraaien tot je bij rechtdoor kijkende sensor die grote afstand hebt, vervolgens rechtdoor).

Dit is precies waar ik uiteindelijk naar toe wil.
Mijn robot krijgt straks een draaibaar hoofd op een servo.

Dat stukje code van Lucky Luke is voor mij nog wartaal, maar het pricipe kan ik er toch wel een beetje van begrijpen

Let wel! Dit wordt mijn eerste zelfgeschreven programma (ledje aan/ledje uit buiten beschouwing gelaten)
verder ben ik nog een volslagen leek, en alle hulp is dan ook van harte welkom.

Karel

Lucky Luke

Golden Member

Geeft 'ie nu de afstand in cm op het scherm?

Zoja:
(ik heb even wat in uw code zitten prutsen, het zou nu hetzelfde moeten doen en een melding geven bij minder dan 50cm.)

pic basic code:


Config hs_osc,wdt_off,pwrte_on,BODEN_On,LVP_OFF
 XTAL 4  
 
Dim afstand As Word
Dim zendpuls As Word
Dim echo As Word

Symbol pulsuit = PORTD.2
Symbol ontvang = PORTD.3
DelayMS 500
Cls

While 1 = 1
 
PulsOut pulsuit, 1                  ; zend puls
DelayUS 40                          ; wacht op echo
afstand = PulsIn ontvang,1   
'DelayUS 40                         ; ontvant de echo < dat doet 'ie al met pulsin, dit kan dus weg
afstand = afstand /58 'delen los doen, ik ga de nieuwe waarde nog 's gebruiken.
Print At 1, 1, Dec afstand       ; zet waarde op lcd

if afstand < 50 then 'als de waarde van afstand nu kleiner is dan 50:
print at 2,1, "Dichtbij" 'tekst op het scherm zetten.
'zet hier wat de robot verder moet doen bij deze afstand
end if

 Wend
End

zonee, dan moet die waarde 50 wat anders zijn, dat is experimenteel vast te stellen. (het valt vast ook te berekenen, maar proberen gaat sneller)

Eluke.nl | De mens onderscheid zich van (andere) dieren door o.a. complexe gereedschappen en bouwwerken te maken. Mens zijn is nerd zijn. Blijf Maken. (Of wordt, bijvoorbeeld, cultuurhistoricus)

Hoi Lucky,

Ik heb de, door jou vernieuwde code even onder een andere filename in proton geplakt.
Ik zie, en begrijp wat jij gedaan hebt, maar nu blijft "Dichtbij" continu op mijn display staan.
Moet die regel 2 niet na elke meting ververst worden met CLS, zoja waar precies?
Het lijkt of hij bij het opstarten al meteen die lage waarde oppikt.
Het meten lijkt nu wel mooier te gaan.
En paar vragen ook over de weergave van de meting die ik ook niet opgelost krijg:

1 hij telt, op enkele uitzonderingen na alleen 10-tallen 10, 20,30, enz.
2 na 90cm komt 10 i.p.v. 110, 120, ....

edit// Problemen opgelost!!!

pic basic code:

afstand = afstand /5,8 ; i.p.v. 58
Print At 1, 1, DEC3 afstand       ; DEC veranderd in DEC3

Nu geeft hij mooi de afstand met 3 decimalen en per cm.
Het heeft weer de nodige Errors en grijze haren opgeleverd maar fietsen leer je ook met veel vallen :p
Wederom alvast bedankt voor de "input"

[Bericht gewijzigd door Kareltje op donderdag 27 mei 2010 00:29:09 (20%)

Lucky Luke

Golden Member

cls wist en initialiseert het display. Voor alleen wissen zou je een subroutine kunnen maken die het display vol spaties print:

pic basic code:


Clearscreen:

print at 1,1, "               "
print at 2,1, "               "
return

Dat kost ook wat minder tijd om uit te voeren. (cls wacht een tiental miliseconden)

Als je het display elke meting wist kan het een beetje gaan knipperen, dat ligt er aan hoe snel je meet.

pic basic code:


if afstand < 50 then 'als de waarde van afstand nu kleiner is dan 50:
print at 2,1, "Dichtbij" 'tekst op het scherm zetten. 
'zet hier wat de robot verder moet doen bij deze afstand
else
gosub clearscreen 'of print at 2,1, "        ", om alleen "dichtbij" te wissen
'of: print at 2,1, "ver weg "
end if
End

floating-point (commagetallen) rekenen kost trouwens behoorlijk wat code en tijd op een microcontroller. Geen probeem als het niet snel hoeft en er genoeg geheugen is, maar als delen door 6 ook een goed genoeg resultaat geeft... zou ik dat doen.
(zeker omdat 6 een macht van 2 is, gaat dat héél veel sneller, en heeft het flink minder programmageheugen nodig)

EDIT @Hvwieren: sorry... Zat net hetzelfde te bedenken en in m'n post te editten...

Eluke.nl | De mens onderscheid zich van (andere) dieren door o.a. complexe gereedschappen en bouwwerken te maken. Mens zijn is nerd zijn. Blijf Maken. (Of wordt, bijvoorbeeld, cultuurhistoricus)

code zo aanpassen dat wanneer de gemeten waarde > 50 is er niets op regel 2 komt.

dus:

pic basic code:


 
if afstand < 50 then 'als de waarde van afstand nu kleiner is dan 50:
    print at 2,1, "Dichtbij" 'tekst op het scherm zetten.
else
    print at 2,1, "        " 'geen tekst op het scherm zetten.
    'zet hier wat de robot verder moet doen bij deze afstand
end if

[Bericht gewijzigd door hvwieren op donderdag 27 mei 2010 16:40:52 (45%)

@ Lucky:
de tekst op het scherm weergeven gaat nu prima,
Het wisselen tussen "zoeken" en "dichtbij" ging gisteren niet echt lekker.
Om het vorige woord op regel2 te wissen lukte mij niet.
Of hij wiste alles, of hij overschreef "dichtbij" waarbij er een deel van het woord liet staan: "zoekenij".
Dit heb ik opgelost door 2 spaties erbij te geven: "zoeken "
Tja....tis niet de juiste weg, ik weet het.
Het delen door 6 geeft nu best wel een goed resultaat, het komt immers niet op millimeterm maar binnen een marge van 2cm zit ik toch wel.
Over de juiste formules heb ik ook gelezen om exact de afstand op het sisplay weer te geven, maar ik heb me hier nog niet echt in verdiept.

@ hvwieren:
Ik had het inmiddels al zo gedaan:

pic basic code:

If afstand < 50 Then                'als de waarde van afstand nu kleiner is dan 50:
Print At 2,1, "Dichtbij"            'tekst op het scherm zetten. 
                                    'zet hier wat de robot verder moet doen bij deze afstand
ElseIf afstand > 50 Then            'als de waarde van afstand nu kleiner is dan 50:
Print At 2,1, "zoeken   "           'tekst op het scherm zetten.
EndIf

De teksten op het display is nu nog allemaal lering.
Als alle codes van mijn sensoren, en servos, in picbasic goed werken,
dan ga ik alles samenvoegen en gaat mijn display alleen maar voor controle dienen.
edit//
nu moet de sensor binnen 50cm een ledje laten branden
Dit wil nog niet lukken
Hetvolgende heb ik nu gedaan:

pic basic code:

While 1 = 1

PulsOut pulsuit, 1                  ; zend puls
DelayUS 40                          ; wacht op echo
afstand = PulsIn ontvang,1          ; ontvant de echo 
afstand = afstand /6              ; deeld be waarde door 5,8 voor cm
Print At 1, 1, DEC3 afstand         ; zet waarde op lcd
 
If afstand < 50 Then                'als de waarde van afstand nu kleiner is dan 50:
Print At 2,1, "Dichtbij"            'tekst op het scherm zetten. 
If afstand < 50 Then                    ;hier moet nu een ledje branden
PORTA.3 = 1
Else PORTA.3 = 0  
EndIf                 'zet hier wat de robot verder moet doen bij deze afstand
ElseIf afstand > 50 Then            'als de waarde van afstand nu kleiner is dan 50:
Print At 2,1, "zoeken   "           'tekst op het scherm zetten.
EndIf
Wend

End

wat zit hier nog fout?

Lucky Luke

Golden Member

Een elseif na een endif, valt de compiler daar niet over?

Is porta.3 een uitgang?
(In te stellen door TRISA.3 0 te maken, of door high porta.3 te gebruiken, dan wordt 'ie als uitgang ingesteld en gelijk hoog gemaakt.)

Staat er niet toevallig nog een analoge comparator op die pin aan oid?
(bij de 16f628A zitten die ergens op porta. Ik weet niet waar want ik heb ze nog nooit gebruikt)

(all_digitall = true bovenaan het programma zet ze uit)

Het stukje van de elsif kan trouwens ook na de else. Wat na de else komt wordt uitgevoerd als de afstand niet kleiner is dan 50. Dat kan maar op 1 manier, namelijk als de afstand 50 of groter is.

Met je huidige code wordt het scherm dus niet ververst als de afstand precies 50 is :) Lijkt me een nodeloze feature...

Eluke.nl | De mens onderscheid zich van (andere) dieren door o.a. complexe gereedschappen en bouwwerken te maken. Mens zijn is nerd zijn. Blijf Maken. (Of wordt, bijvoorbeeld, cultuurhistoricus)

Ik heb het inmiddels voor mekaar gekregen door de tris regel erbij te zetten.
Nu gaat het ledje aan, als de afstand < 50 is, en uit boven de 50

De code zoals die nu is:

pic basic code:

While 1 = 1

PulsOut pulsuit, 1                  ; zend puls
DelayUS 40                          ; wacht op echo
afstand = PulsIn ontvang,1          ; ontvant de echo 
afstand = afstand /6              ; deeld be waarde door 5,8 voor cm
Print At 1, 1, DEC3 afstand         ; zet waarde op lcd
 
If afstand < 50 Then                'als de waarde van afstand nu kleiner is dan 50:
Print At 2,1, "Dichtbij"            'tekst op het scherm zetten. 
 
ElseIf afstand > 50 Then            'als de waarde van afstand nu kleiner is dan 50:
Print At 2,1, "zoeken   "          'tekst op het scherm zetten.
EndIf
If afstand < 50 Then                    ;hier moet nu een ledje branden
PORTA.3 = 1
Else PORTA.3 = 0 
EndIf
Wend

End

Ik was nu aan het proberen om de metingen wat stabieler te krijgen.
Op het randje van 50 cm gaat het ledje nogal zenuachtig knipperen.
Mede door bijgeluiden (waarschijnlijk) en door mijn bewegingen.
Is er tussen 2 metingen een vertraging in te bouwen, zodat de metingen wat stabieler weergegeven worden?
Ik had het al geprobeerd, maar het heeft steeds invloed op de pulsfrequentie.
Ik was ook al druk aan het 'studeren' op picbasic.nl en het lijkt mij straks beter om allemaal subrotines te gaan maken.
Hoe precies, weet ik nog niet, daar ben ik nog te 'dummy' voor.
Maar eerst wil ik al mijn sensoren naar behoren werkend krijgen.
Daarna het programma om "Johnny" hiermee op pad te sturen.

Lucky Luke

Golden Member

Het kan nog compacter:

pic basic code:


While 1 = 1
 
PulsOut pulsuit, 1                  ; zend puls
DelayUS 40                          ; wacht op echo
afstand = PulsIn ontvang,1          ; ontvant de echo 
afstand = afstand /6              ; deeld be waarde door 5,8 voor cm
Print At 1, 1, DEC3 afstand         ; zet waarde op lcd
 
If afstand < 50 Then                'als de waarde van afstand nu kleiner is dan 50:
Print At 2,1, "Dichtbij"            'tekst op het scherm zetten. 
PORTA.3 = 1
 
ElseIf afstand > 50 Then            'als de waarde van afstand nu Groter is dan 50:
Print At 2,1, "zoeken   "          'tekst op het scherm zetten.
porta.3 = 0
EndIf

Wend
 
End

Subroutines?

pic basic code:


While 1 = 1
gosub sensorlees
Print At 1, 1, DEC3 afstand         ; zet waarde op lcd
gosub waardeverglijk
wend 

sensorlees:

PulsOut pulsuit, 1                  ; zend puls
DelayUS 40                          ; wacht op echo
afstand = PulsIn ontvang,1          ; ontvant de echo 
afstand = afstand /6              ; deel de waarde door 5,8 voor cm
return

waardeverglijk: 

If afstand < 50 Then                'als de waarde van afstand nu kleiner is dan 50:
Print At 2,1, "Dichtbij"            'tekst op het scherm zetten. 
PORTA.3 = 1
 
ElseIf afstand > 50 Then            'als de waarde van afstand nu Groter is dan 50:
Print At 2,1, "zoeken   "          'tekst op het scherm zetten.
porta.3 = 0
EndIf
return

 
End
Eluke.nl | De mens onderscheid zich van (andere) dieren door o.a. complexe gereedschappen en bouwwerken te maken. Mens zijn is nerd zijn. Blijf Maken. (Of wordt, bijvoorbeeld, cultuurhistoricus)

Je hebt er echt werk van gemaakt Lucky, bedankt hiervoor :)
Hiermee ga ik aan de slag, en hoop snel resultaten te laten zien.
Je hebt mooie voorbeelden laten zien.
Gelukkig heb je niet alles in hapklare brokken geleverd, zodat ik alleen maar copie en plakwerk hoef te maken.
Maar een flinke duw in de rug helpt wel :)
IK ga mijn breadboard eens vol prikken en ga met bovenstaande eens aan de slag.

Thnx... Karel

De eerste versie van de hoofdprint is klaar
Hieronder een foto om mijn vragen wat duidelijker te omschrijven

http://www.uploadarchief.net/files/download/hoofdprint%20johnny6.jpg

Het is de bedoeling om (voorlopig) met een tv-afstandbediening de robot te besturen.
Het hart van Johnny6 is de pic 16F877A.
De manualbesturing en de sensor modi worden met de afstandbediening in- of uitgeschakeld via de 16F630 (picbasic.nl).
bovenaan op de foto een rij headers om div. sensors aan te sluiten met evt. pull-up weerstanden.
Links op de print een 16F628 en een L293D om de robot door de knieen te laten gaan.
verder enkele rijen met headers om evt. leds op het bedieningspaneeltjepaneeltje aan te sluiten en een directe bediening zonder afstandbediening.

(opbouwende) kritiek op deze print, en de opzet, is van harte welkom.

Het programma in het kort:
manualbesturing vooruit/achteruit/links/rechts.
IR-mode: opstakels vermijden
Lichtmode: schaduw van de zon vermijden of in het donker op lichtbronnen af gaan
ultrasoonmode: stoppen bij opstakel, en de beste doorgang vinden via het draaibare hoofd.
geluidsmode: op geluid reageren

Plannen genoeg :) nu de uitvoering nog
programmatests voor IR, ultrsoon, en de servo voor het hoofd werken nu naar behoren.
Nu mijn vragen:
Ik wil met subroutines werken die telkens terugkeren naar het hoofdprogramma van waaruit ik met de afstandbediening een mode kies.
Hoe kan ik een subroutine die ik eenmaal aangeroepen heb, later weer uitschakelen?
b.v. Ik druk op toets 2 = robot rijd vooruit
dan toets 1 IR-mode nu gaat de robot alle opstakels vermijden.
dan toets 3 Ultrasoon wordt ingeschakeld, maar nu moet wel IR uitgeschakeld worden.
Kan ik nu het beste de ingang vna IR hoog maken, zodat die door de sensor niet laag gemaakt kan worden?
Of moet ik de subroutine voor IR beeindigen, en hoe?
Ik kan ook met toets 5 de robot laten stoppen en alles resetten?

Ik ben met het programmeren nu zover dat ik de poorten gedefineerd heb en de subroutines aangemaakt heb.
Maar voor ik echt verder ga, maar totaal fout bezig ben, zou ik graag jullie mening hierover horen.
Zoals ik al eerder aangaf, ben ik pas begonnen met picbasic dus nog veel (bijna alles) te leren.

edit:// de print is getekend met sprintlayout en heb hier verder geen schema van

Mvgr. Karel

kan de L293D wel genoeg stroom leveren om de motor's aan te sturen?

Op 5 juni 2010 16:46:14 schreef robojan:
kan de L293D wel genoeg stroom leveren om de motor's aan te sturen?

Belast gebruiken deze motoren 300 mA en de L293D kan 600 mA verwerken

Lucky Luke

Golden Member

er draait maar 1 subroutine, pas als die klaar is gaat 'ie terug naar het hoofdprogramma. Je kunt er dus niet meerdere tegelijk starten.

Je zal dus in het deelprogramma voor b.v. IRmode ook iets op moeten nemen dat kijkt of er signaal van de afstandsbediening komt, en bij het juiste signaal overschakelen naar b.v. lichtmode.

pic basic code:


irmode:

repeat 
'doe wat IRmode moet doen
'Lees afstandsbediening (zie helppagina van RC5in commando) 
until RC5_command <> 255 'doe IRmode zolang er geen afstandsbedieningssignaal komt
return 'ga terug naar het hoofdprogramma
'in het hoofdprogramma moet dan weer iets staan dat a.d.h.v. het ontvangen
afstandsbedieningssignaal iets doet. B.v. naar lichtmode gaan.
Eluke.nl | De mens onderscheid zich van (andere) dieren door o.a. complexe gereedschappen en bouwwerken te maken. Mens zijn is nerd zijn. Blijf Maken. (Of wordt, bijvoorbeeld, cultuurhistoricus)

Hey Lucky, blij dat er iemand reageerd op mijn programma.
Ik zat hopeloos vast.

Even voor de duidelijkheid:
die 16f630 is die van picbasic.nl IR-10 uitgangen in de puls uitvoering.
Deze geeft dus een hoog signaal af naar de 16F877A als ik een toets in druk.
b.v.
toets 2 geeft een puls aan portd.6 van de 16F877

zo ook toets 1 is de IR-mode
hieronder een stukje code zoals ik met alle toetsen heb ingevoerd.
als voorbeeld de IR-mode
Ik hoef dus in die 16F877 geen RC5 code in te bouwen, die staat er al helemaal los van.

pic basic code:

ir_aan:                                         'Infraroodsensor inschakelen
    Repeat                                      'Herhalen
        If irsens1 = uit Then
            linksen = aan
            motorlv = aan
            rechtsen = aan
            motorra = aan
        Else motorlv = aan
            motorrv = aan
        EndIf
    Until toets3, 1 toets5, 1 toets7, 1 toets9, 1   'deze lus beeindigen totdat er een aandere mode geselekteerd word
       GoSub hoofdprogramma

         
hoofdprogramma:                                 'Hoofdprogramma
    While 1 = 1
            If toets1 = aan Then
            GoSub ir_aan
        EndIf
            If toets2 = aan Then
            GoSub vooruitrijden
        EndIf
            If toets4 = aan Then
            GoSub linksaf
        EndIf
            If toets8 = aan Then
            GoSub achteruitrijden
        EndIf
            If toets3 = aan Then
            GoSub ultrasoon
            EndIf
        
    Wend

End

Waarschijnlijk is dit helemaal fout, maar wat?

de bedoeling is dat er straks ook een irsens2 komt
Ik was net alles op mijn printje aan het monteren.
de afstandbediening werkte mooi, maar ik kreeg geen reactie op mijn commando's

Lucky Luke

Golden Member

Ok, als ik het goed begrijp gebruik je dit ?
Wat er dan voor zorgt dan RC5 commando's gelezen worden en vervolgens een ingang op de 16f877A een signaal krijgt.

Hmm... hmm... Maakt de code in de 16F877A makkelijker, omdat die dan geen afstandsbediening meer hoeft in te lezen.

Heb je 'm op togle of op pulse staan?

b.v.
toets 2 geeft een puls aan portd.6 van de 16F877

Pulse dus?

Goed. Dan ga ik nu ff gaten schieten in de code, en daarnaast wat gedachten laten ontsnappen :)

Gosub hoofdprogramma -> (dubbelloops) BLAM! (zit nu een gat)

Gosub is voor subroutines. Om ergens naar toe te gaan zonder het doel terug te komen is er goto. Maar teveel goto's zijn onoverzichtelijk, dus vermijd ze.
(Aangezien er met gosub naar IR_aan gesprongen wordt kun je daar waar nu gosub hoofdprogramma staat return neerzetten.)

bij de repeat-until: Het commentaar hinkt een beetje op 2 gedachten volgens mij... ;)

Verder denk ik dat de compiler ook valt over die regel. Ik denk dat er iets als until toets3 = 1 OR toets5 = 1 OR toets7 = 1 OR toets9 = 1 moet staan...

En ik ga er nu van uit dat Toets1 gelijk staat aan de ingang waar de desbetreffende uitgang van de andere PIC op zit? dus dat er ergens bovenaan iets als symbol toets1 portx.y staat? (idem voor dingen als irsens, linksen, uit en aan). Het maakt de code wel duidelijker om op deze manier te verwijzen, want dan hoef je niet meer te denken "wat was portb.4 ook alweer"?

Zit het schermpje wel op de 16F877? (te zien aan de print wel) Dan zou je even het stukje afstandsbediening (en subroutines) los kunnen testen door naar verschillende subroutines te springen, die dan een tekst op het schermpje zetten en de mogelijkheid bieden terug te springen. Als tekst b.v. naam van de subroutine + welke ir ingangen er hoog zijn.

[END OF INPUT] so far...

Hoe staat het eigenlijk met het mechanisch gedeelte? Rijdt 'ie al? (zei het dan nog onintelligent)

Eluke.nl | De mens onderscheid zich van (andere) dieren door o.a. complexe gereedschappen en bouwwerken te maken. Mens zijn is nerd zijn. Blijf Maken. (Of wordt, bijvoorbeeld, cultuurhistoricus)

Hoi Lucky,

Ik weet het, dat er veel aan mijn code mankeerd, vandaar ik jouw (jullie) hulp inroep,

Jouw gedachten liggen precies op dezefde lijn als de mijne.
Het is inderdaad zo dat de uitgangen van die ir-chip (16F630) op de ingangen van de 16F877 zitten.
Het maakt het proggen inderdaad eenvoudiger, en ik heb bewust de puls-versie gebruikt daar ik anders die ingangen niet softwarematig weer laag krijg.
Wat die gosubs betreft, hier had ik al eg mijn twijfels over, maar kon geen goede codes bedenken waarvan ik zekerder was.
Aan de hand van voorbeelden op picbasic ben ik hiermee op deze manier aan de slag gegaan.
Maar ik zal hieronder zometeen de voledige code neerzetten, zoals die op dit moment is.
Hierop kun jij je er met jou dubbeloops op uitleven.

Wat het mechanische deel betreft.... Ik ben nu met aandrijving versie 3 bezig.
Versie 1 was een v-snaartje met bijbehorende poelies.
Maar die bleven slippen, maar werkte wel
versie 2 was een tandriemaandrijving.
Ik kon die riemschijven niet genoeg aanpassen dat ze werkten of ik moest 2 nieuwe zijplaten laten snijden zodat ik mijn motoren verder terug kon laten vallen.
Ik had die platen al zover op tekening aangepast dat ze alleen nog maar gesneden hoefde te worden.
Toen kwam versie 3 in mijn gedachte (kettingaandrijving)
Bij een klant van ons een stuk ketting geritseld met mooie kleine schakels en kettingwieltjes getekend (3 maten van ieders 2)
Voordeel hiervan: minimale wrijving en te wieltjes zijn klein genoeg om ergens tussen een laseropdracht tussen te nesten (gratis dus:))
Ik verwacht ze volgende week bij ons op het bedrijf zodat weer verder kan bouwen.
Alle connectoren voor de accu, motoren, en sensors heb ik inmiddels, dus het rijden zal niet lang meer duren.

Zo, weer een (te?)lang verhaal over mijn vorderingen.
Hieronder nu mijn huidige code:

pic basic code:

Device 16F877A
Config hs_osc,wdt_off,pwrte_on,BODEN_On,LVP_OFF
 XTAL 20  
 
Dim afstand As Word
Dim zendpuls As Word
Dim echo As Word
 
Symbol pulsuit = PORTB.0
Symbol ontvang = PORTB.1
Symbol ir =     PORTB.1
Symbol toets1 = PORTD.7
Symbol toets2 = PORTD.6
Symbol toets3 = PORTD.5
Symbol toets4 = PORTD.4
Symbol toets5 = PORTC.7
Symbol toets6 = PORTC.6
Symbol toets7 = PORTD.2
Symbol toets8 = PORTD.3
Symbol toets9 = PORTC.4
Symbol toets0 = PORTC.5
Symbol motorlv =  PORTC.2
Symbol motorla =  PORTD.0
Symbol linksen =  PORTC.0
Symbol motorrv =  PORTC.1
Symbol motorra =  PORTC.3
Symbol rechtsen = PORTD.1
Symbol bukken =   PORTE.2
Symbol irsens1 =  PORTE.0
Symbol irsens2 =  PORTA.4
Symbol uit = 0
Symbol aan = 1

        ;76543210
PORTA = %00111111 
PORTB = %00000000
PORTC = %00000000 
PORTD = %00000000
PORTE = %00000011
TRISA = %00111111
TRISB = %11111110
TRISC = %11110000 
TRISD = %11111100
TRISE = %00000011

DelayMS 500

GoSub hoofdprogramma

vooruitrijden:

    Repeat
        If toets2 = aan Then                    'vooruit rijden
            rechtsen = aan
            linksen = aan
            motorlv = aan
            motorrv = aan
        EndIf
    Until toets5, 1
        GoSub hoofdprogramma

achteruitrijden:

    Repeat                                      'Achteruit rijden
        If toets7 = aan Then
            linksen = aan
            rechtsen = aan
            motorla = aan
            motorra = aan
            EndIf
    Until toets5, 1
        GoSub hoofdprogramma 
        
rechtsaf:

    Repeat
        If toets6 = aan Then
             linksen = aan
            rechtsen = aan
            motorlv = aan
            motorra = aan
            EndIf
    Until toets5, 1
    GoSub hoofdprogramma
    
linksaf:                                        'rechtsaf draaien
    Repeat
        If toets4 = aan Then
            linksen = aan
            rechtsen = aan
            motorrv = aan
            motorla = aan
            EndIf 
    Until toets5, 1
    GoSub hoofdprogramma
    
ultrasoon:                                      'Ultrasoon inschakelen
    Repeat
        If toets1 = aan Then
            toets3 = uit
            toets7 = uit
            toets9 = uit
            EndIf 
            Print At 1, 1, DEC3 afstand         'zet waarde op lcd
             
            PulsOut pulsuit, 1                  'zend puls
            DelayUS 40                          'wacht op echo
            afstand = PulsIn ontvang,1          'ontvant de echo 
            afstand = afstand /6                'deel de waarde door 5,8 voor cm
            If afstand < 50 Then                'als de waarde van afstand nu kleiner is dan 50:
            Print At 2,1, "Dichtbij"            'tekst op het scherm zetten. 
         
            ElseIf afstand > 50 Then            'als de waarde van afstand nu Groter is dan 50:
            Print At 2,1, "zoeken   "           'tekst op het scherm zetten.
            EndIf
    Until toets1, 1 toets5, 1 toets7, 1 toets9, 1
        GoSub hoofdprogramma   

ir_aan:                                         'Infraroodsensor inschakelen
    Repeat                                      'Herhalen
        If irsens1 = uit Then
            linksen = aan
            motorlv = aan
            rechtsen = aan
            motorra = aan
        Else motorlv = aan
            motorrv = aan
        EndIf
    Until toets3, 1 toets5, 1 toets7, 1 toets9, 1   'deze lus beeindigen totdat er een aandere mode geselekteerd word
       GoSub hoofdprogramma

         
hoofdprogramma:                                 'Hoofdprogramma
    While 1 = 1
            If toets1 = aan Then
            GoSub ir_aan
        EndIf
            If toets2 = aan Then
            GoSub vooruitrijden
        EndIf
            If toets4 = aan Then
            GoSub linksaf
        EndIf
            If toets8 = aan Then
            GoSub achteruitrijden
        EndIf
            If toets3 = aan Then
            GoSub ultrasoon
            EndIf
        
    Wend

End

Groetjes Karel

Lucky Luke

Golden Member

Een verhaal over de voortgang van een leuk project is nooit te lang :)

Maar die gosubs kloppen niet.

Gosub is voor subroutines. Om ergens naar toe te gaan zonder het doel terug te komen is er goto. Maar teveel goto's zijn onoverzichtelijk, dus vermijd ze.

(Aangezien er met gosub naar IR_aan gesprongen wordt kun je daar waar nu gosub hoofdprogramma staat return neerzetten.)

Bij de eerste gosub hoofdprogramma, bovenin je programma. Daar wil je helemaal niet naar terugspringen. Dus dat moet geen go sub zijn, maar een go to.

Bij de andere gosub hoofdprogramma's, onderaan de subroutines: daar wil je helemaal niet naar een subroutine "hoofdprogramma", daar wil je terugkeren naar waar je vandaan kwam. Return dus.

Verder zitten bij de until's nog steeds constructies als "toets1, 1" valt de compiler daar niet over? (zie mijn vorige post)

En volgens mij zet je motoren aan in de subroutines, maar niet meer uit als je terugkeert naar het hoofdprogramma... Robot op hol!

En het aanzetten van die motoren hoeft ook niet herhaalt te worden, die blijven wel aan. Je kunt ze dus aan het begin van je subroutine aanzetten, en daarna pas de repeat - until lus ingaan. In die lus kun je dan b.v. de ultrasoon meting doen. Dan kun je in die until nog iets zetten dat 'ie niet alleen uit de lus moet springen bij toets 5, maar ook bij een te kleine afstand. Vervolgens nog even testen of het toets5 was of de afstand, en bij toets5 naar het hoofdprogramma teruggaan (if toets5 = 1 then ... end if). Als het niet toets5 was de actie uitvoeren die bij een te kleine afstand hoort, en daarna weer opnieuw beginnen met de subroutine. Bijvoorbeeld.

Het commentaar "deze lus beeindigen totdat er een aandere mode geselekteerd word" klopt ook niet. De lus wordt uitgevoerd totdat er een andere mode geselecteerd wordt, of beeindigdt als er een andere mode geselecteerd wordt. Waarschijnlijk bedoelde je dat ook te zeggen maar is het een beetje doorelkaar gehusseld.

Zo, de code is nu gatenkaas :)

Eluke.nl | De mens onderscheid zich van (andere) dieren door o.a. complexe gereedschappen en bouwwerken te maken. Mens zijn is nerd zijn. Blijf Maken. (Of wordt, bijvoorbeeld, cultuurhistoricus)

Hoi Lucky,
Bij een goede gatenkaas, gaat het erom wat er TUSSEN de gaten zit ;)
Als er tenminste nog wat bruikbaars tussen zit.

Ik was gisteren wat erg laat thuis om nog iets aan mijn code te doen.
Ik heb hooguit jouw opmerkingen voor aanpassingen goed bestudeerd, en daarna een en ander toegelicht en wat vragen erover gesteld, zie ik nu pas, dat ik na preview vergeten ben op 'posten' te drukken |:(
Dus nu weer overnieuw:
Dat hele GOSUB gebeuren heb ik nooit niet erg goed begrepen, zelfs niet na die goede voorbeelden van Frits.
Ik begreep eruit, dat je van de ene gosub naar de andere moest springen om diverse funkties en handelingen uit te voeren of te beeindigen.
Vandaar ook die vele herhalingen, wat die motoren betreft.

Bij de andere gosub hoofdprogramma's, onderaan de subroutines: daar wil je helemaal niet naar een subroutine "hoofdprogramma", daar wil je terugkeren naar waar je vandaan kwam. Return dus.

Return zag ik als herhaling voor dezelfde subroutine (niet dus)

Verder zitten bij de until's nog steeds constructies als "toets1, 1" valt de compiler daar niet over? (zie mijn vorige post)

Nee, proton heeft er geen enkele moeite mee, het werdt toch ook toegepast bij dat ultrasoon gebeuren?

pic basic code:

afstand = PulsIn ontvang,1          'ontvant de echo 

1 = high
Heb ik inmiddels wel aangepast

En volgens mij zet je motoren aan in de subroutines, maar niet meer uit als je terugkeert naar het hoofdprogramma... Robot op hol!

inderdaad op hol, als ik vergeten ben om toets5 (STOP!!)in te voeren.

Het commentaar "deze lus beeindigen totdat er een andere mode geselekteerd word" klopt ook niet

todat moest zijn: zodra
Als ik nu goed begrijp, w.b. subroutines, deze worden vanzelf beeindigd als ik via toets1, toets2 etc. een andere subroutine aanspreek?
Voor linksaf cq rechtsaf, rechtdoor, of achteruit, moet ik toch wel telkens aangeven welke uitgangen naar die L293D geaktiveerd worden?
Kan ik die funkties beter in het hoofdprogramma zetten, i.p.v. aparte subroutines?

Ik ga nu een totale nieuwe code schrijven, en kom hier later weer op terug.

Wederom hardstikke bedankt voor de "INPUT"

[beetje offtopic]
De robot in onderstaand filmpje is nu in bezit van een uniformen en props verhuurbedrijf. Het is een voormalige orginele EOD-robot
Bij deze man werk ik op Dinsdagavond altijd en heb er gisterenavond een tijdje mee 'gespeeld'
Dit gaat ook een project voor mij worden.
O.a. aanpassingen aan de RC-besturing, en hem voorzien van een grijper.
Hierover later meer in een ander topic.

http://www.youtube.com/watch?v=Vy9L0b692Uo

[ontopic] (wordt vervogd)

Inderdaad het principe van gosubs en goto's is je nog niet helemaal duidelijk.

Je gebruikt een goto als je niet meer van plan ben om terug te keren naar waar je vandaan kwam.
bv:

/..
initialiseren
../
goto hoofdprogramma ;hier "spring" je naar het hoofdprogramma met de intensie om hier niet meer terug te komen. hier moet je dus goto gebruiken.

Nou ben je in je hoofdprogramma.

Daarin zeg je:

Ga naar bijvoorbeeld rechtsom draaien en kom hier terug als je daar mee klaar bent. oftewel je wilt weer in het hoofdprogramma terugkomen.

het wordt dus:

hoofdprogramma:
begin lus
/..
je programma
../
gosub rechtsom ;je gaat hier naar de subroutine rechtsom en keert terug als je klaar bent. en gaat dan in de volgende regel verder.
/..
rest van je programma
../
einde lus

Ik hoop dat het zo duidelijker is. In principe heeft Lucky Luke het ook zo uitgelegd maar misschien is het anders verwoorden duidelijker.

MVG bas.

Hoi Bas,
Zoals je gemerkt hebt, en als je deze topic een beetje gevolgd hebt, ben ik in picbasic nog een echte leek.
Picbasic.nl staat dan hier ook ten alle tijden geopend om voorbeelden te bekijken, te bestuderen, en stap voor stap uit te voeren.
Een ledje aan/uitzetten, een lcd aansturen, motoren met een l293D is allemaal geen probleem meer.
Zowel de IR-sensor als de Ultrasoon sensor heb los van de rest allemaal werkend gekregen.
Het is nu zover dat ik al die elementen in 1 programma samen moet voegen, en met elkaar kunnen laten werken.
Om die robot met meerdere modi te laten werken, wou ik dat via subrotines doen (zie een stuk terug)
Zoals ik al eerder zei: dit is mijn eerste echte programma dat ik helemaal uit wil werken tot een werkende robot, die naar al mijn wensen functioneerd.
Later wil ik er steeds meer in bouwen dus ook de nodige software updates.
Het is 1 van mijn 2 grootste doelstellingen: picbasic leren, en gebruiken.

Ook jij bedankt voor de nodige "input"

Karel

Hoi allemaal,

Na een paar daagjes picbasic en wat mechanische vorderingen weer tijd voor een update.

Picbasic.... wat werkt wel, en wat nog niet?
Ik ben nu zover dat ik met de afstandbediening de motoeren alle richtingen op kan sturen Toet2, 4, 6, en 8
Werkt allemaal prima ook toets5 (=stop)
wanneer in nu op toets1 cq toets3 druk, dan worden zoals bedoeld de verschillende sensors in- of uigeschakeld.
bij de ir-mode draaien de motoren nog 2 sec door.

pic basic code:

ir_aan:                                         'Infraroodsensor inschakelen

    Repeat                                      'Herhalen
            motorlv = hoog                                
            motorrv = hoog
        If irsens1 = laag Then                  'linkersensor ziet opstakel
            motorlv = hoog
            motorra = hoog
    DelayMS 2000                                'robot draait nog 2 sec. door
            motorlv = hoog
            motorrv = hoog
        EndIf
        If irsens2 = laag Then                  'rechtersensor ziet opstakel
            motorrv = hoog
            motorla = hoog
    DelayMS 2000                                'robot draait nog 2 sec. door
            motorlv = hoog
            motorrv = hoog
        EndIf
    Until toets3 = hoog toets5 = hoog toets7 = hoog toets9 = hoog   'deze lus beeindigen wanneer er een aandere mode geselekteerd word
Return[/code=picbasic]
Hier aan gekomen kom ik er helemaal niet meer uit.
Geen enkele toets reageerd dan nog, dit geldt ook voor de ultrasoonsensor.

Ik heb onderaan de subroutines returns geplaatst ipv die gosubs.
Waarom kan ik na toets1 entoets3 geen enkele toets meer aanspreken?
heb ik iets fout gedaan met REPEAT en UNTIL?
Volgens de proton handleiding 'lijkt' deze code toch juist.

Please "NEED INPUT"

De gehele code:
[code=picbasic]Device 16F877A
Config hs_osc,wdt_off,pwrte_on,BODEN_On,LVP_OFF
 XTAL 20  
 
Dim afstand As Word
Dim zendpuls As Word
Dim echo As Word
 
Symbol pulsuit = PORTB.1
Symbol ontvang = PORTB.0
Symbol toets1 = PORTD.7
Symbol toets2 = PORTD.6
Symbol toets3 = PORTD.5
Symbol toets4 = PORTD.4
Symbol toets5 = PORTC.7
Symbol toets6 = PORTC.6
Symbol toets7 = PORTD.2
Symbol toets8 = PORTD.3
Symbol toets9 = PORTC.4
Symbol toets0 = PORTC.5
Symbol motorlv =  PORTC.2
Symbol motorla =  PORTD.0
Symbol linksen =  PORTC.0
Symbol motorrv =  PORTC.1
Symbol motorra =  PORTC.3
Symbol rechtsen = PORTD.1
Symbol bukken =   PORTE.2
Symbol irsens1 =  PORTE.0
Symbol irsens2 =  PORTA.4
Symbol laag = 0
Symbol hoog = 1

        ;76543210
PORTA = %00111111 
PORTB = %00000000
PORTC = %00000000 
PORTD = %00000000
PORTE = %00000011
TRISA = %00111111
TRISB = %11111101
TRISC = %11110000 
TRISD = %11111100
TRISE = %00000011

DelayMS 500
Cls

Print At 1, 6, "Hallo"
Print At 2, 2, "Ik ben Johnny 6"
DelayMS 2000
Print At 1, 3, "READY TO GO !!"
Print At 2, 1, "                "
DelayMS 2000
Cls

Clear
GoTo hoofdprogramma

ultrasoon:                                      'Ultrasoon inschakelen
     Repeat
   
            Print At 1, 1, DEC3 afstand         'zet waarde op lcd             
            PulsOut pulsuit, 1                  'zend puls
            DelayUS 40                          'wacht op echo
            afstand = PulsIn ontvang,1          'ontvant de echo 
            afstand = afstand /6                'deel de waarde door 5,8 voor cm
        If afstand < 50 Then                    'als de waarde van afstand nu kleiner is dan 50:
            Print At 2,1, "Dichtbij"            'tekst op het scherm zetten. 
         
            ElseIf afstand > 50 Then            'als de waarde van afstand nu Groter is dan 50:
            Print At 2,1, "zoeken   "           'tekst op het scherm zetten.
            EndIf
    Until toets1 = hoog toets5 = hoog toets7 = hoog toets9 = hoog
Return
    
ir_aan:                                         'Infraroodsensor inschakelen

    Repeat                                      'Herhalen
            motorlv = hoog                                
            motorrv = hoog
        If irsens1 = laag Then                  'linkersensor ziet opstakel
            motorlv = hoog
            motorra = hoog
    DelayMS 2000                                'robot draait nog 2 sec. door
            motorlv = hoog
            motorrv = hoog
        EndIf
        If irsens2 = laag Then                  'rechtersensor ziet opstakel
            motorrv = hoog
            motorla = hoog
    DelayMS 2000                                'robot draait nog 2 sec. door
            motorlv = hoog
            motorrv = hoog
        EndIf
    Until toets3 = hoog toets5 = hoog toets7 = hoog toets9 = hoog   'deze lus beeindigen wanneer er een aandere mode geselekteerd word
Return  
       
hoofdprogramma:

While 1 = 1
linksen = hoog  
rechtsen = hoog                            
    If toets2 = hoog Then                       'rechtdoor rijden
        motorlv = hoog
        motorrv = hoog
    EndIf
    If toets4 = hoog Then                       'rechtsaf draaien
        motorrv = hoog
        motorla = hoog
    EndIf
    If toets5 = hoog Then                       'stop!!
        motorlv = laag
        motorrv = laag
        motorra = laag
        motorla = laag
    EndIf
    If toets6 = hoog Then                       'rechtsaf draaien
        motorlv =hoog
        motorra = hoog  
        motorrv = laag
        motorla = laag
    EndIf
    If toets8 = hoog Then                       'achteruit rijden
        motorla = hoog
        motorra = hoog
        EndIf 
    If toets1 = hoog Then                       'IR-sensors aan
    Print At 1, 1, "IR-sensors aan" 
    DelayMS 2000
    Cls                      
        GoSub ir_aan                        
    EndIf  
    If toets3 = hoog Then                       'ultrasoonsensor aan
    Print At 1, 1, "ultrasoon"              
    Print At 2, 1, "sensor aan"
    DelayMS 2000
    Cls
        GoSub ultrasoon
    EndIf                           
Wend  

End
  

Wat het mechanisch gedeelte betreft:
Vandaag de wielen uitgelijnd zodat de tracks nu lekker soepel lopen.
Wat kabelgootjes gemaakt, en het lijf 2 cm breder gemaakt.
Het eerste ontwerp was niet op een display berekend. |:(

Nu is het wachten op mijn kettingwieltjes, en dan...de eerste echte proefrit :)

Lucky Luke

Golden Member

Je zet nog steeds motoren aan die al aan zijn af en toe, maar dat is het probleem niet. (Dat is meer een afweging tussen duidelijke of compacte code, en aangezien je voorlopig toch ruimte zat hebt in die 16f877 zou ik voor duidelijk gaan).

Hmm. Je kunt 's uitzoeken waar die blijft hangen door in de subroutine iets op het scherm te laten zetten. Dan na de lus en voor de return. Dan zie je of 'ie wel uit de lus springt.

Ik vraag me af wat PICBASIC doet met "Until toets3 = hoog toets5 = hoog toets7 = hoog toets9 = hoog"... Het komt blijkbaar wel door de compiler...

Je bedoeld "Until toets3 = hoog OR toets5 = hoog OR toets7 = hoog OR toets9 = hoog", maar als PICBASIC er "Until toets3 = hoog AND toets5 = hoog AND toets7 = hoog AND toets9 = hoog" van maakt dan kom je natuurlijk nooit uit die lus, omdat je niet al die ingangen tegelijk hoog kan maken. (Tenzij je de afstandsbedieningsontvangerpic op toggle zet, maar dat brengt weer andere nadelen met zich mee).

Eluke.nl | De mens onderscheid zich van (andere) dieren door o.a. complexe gereedschappen en bouwwerken te maken. Mens zijn is nerd zijn. Blijf Maken. (Of wordt, bijvoorbeeld, cultuurhistoricus)

Hoi Lucky,
Blij je weer te zien :) ik zit er hopeloos mee vast.
Hij blijft hangen, wanneer ik toets 1 of 3 gebruik
Hij zet dan wel heel mooi ir-sensor aan op het scherm, en zo ook met ultrasoon, maar dan moet ik het hele zaakje weer resetten.

Je bedoeld "Until toets3 = hoog OR toets5 = hoog OR toets7 = hoog OR toets9 = hoog"

hier heeft proton wel moeite mee.
Ik wil het nu eens proberen met XOR, dus: toets1 of toets2, maar niet beide etc.
Wat denk jij hiervan?

Effe een klein stukje code van Frits:

pic basic code:

;Hoofdprogramma
WHILE 1 = 1                   ;Oneindige lus
  IF S1 = AAN THEN            ;Als S1 aan is dan...
    HIGH LED1                 ;LED1 aan
    LOW  LED2                 ;LED2 uit
  ELSE                        ;... anders ...
    LOW  LED1                 ;LED1 uit
  ENDIF                       ;Einde IF...THEN...ELSE blok van S1

hier gebruikt hij

pic basic code:

SYMBOL AAN  = 0               ;Schakelaar aan = laag (0)
SYMBOL UIT  = 1               ;Schakelaar uit = hoog (1)

maar ook low en High, zit hier verschil in?
ik gebruik alleen bv.

pic basic code:

motorlv = hoog                                
            motorrv = hoog
        If irsens1 = laag Then                  'linkersensor ziet opstakel
            motorlv = hoog
            motorra = hoog

Of moet ik ook

pic basic code:

High motorrv

gebruiken?

(Tenzij je de afstandsbedieningsontvangerpic op toggle zet, maar dat brengt weer andere nadelen met zich mee).

Ik ben van die togglemode wel een beetje huiverig, ik kan dan niet meer zien wat aan of uit staat, en ik moet dan ten alle tijden elke toets eerst uit zetten alvorens een andere toets weer aan te kunnen zetten.
Een combinatie zou wel werken (denk ik)voor het aan, of uit zetten van de sensors.
Ik ga eerst eens met die repeat en until een wat experimenteren en laat je zo weer wat horen

Groetjes Karel

Lucky Luke

Golden Member

wbt toglemode: dat zijn dus de nadelen waar ik op doelde.

wbt high / low vs. 1/0:
Met high porta.1 gebeurt er het volgende:
DDRA.1 wordt 0 gemaakt (porta.1 wordt dus een 0utput gemaakt)
Porta.1 wordt 1 gemaakt (gaat een hoog signaal afgeven).

Maar als je al eerder zelf de DDR hebt ingesteld hoeft dat niet meer voor elke actie te gebeuren en kan porta.1 = 1 ook.
Dat maakt dan alleen porta.1 1, het zet 'm niet eerst als uitgang.

En als je ergens van tevoren hebt opgegeven dan "aan" 1 betekend, of "hoog" 1 betekend, dan kun je ook porta.1 = hoog schrijven.

Dat is het verschil.

En OR of XOR zou hier niks uit moeten maken... Een situatie waarbij meerdere ingangen hoog zijn zou niet voor moeten komen. En dan nog is het niet erg als 'ie daar ook op reageert. De compiler zal er ook even hard over vallen.

Probeer anders eens met haakjes "Until (toets3 = hoog OR toets5 = hoog) OR (toets7 = hoog OR toets9 = hoog)" oid.

Eluke.nl | De mens onderscheid zich van (andere) dieren door o.a. complexe gereedschappen en bouwwerken te maken. Mens zijn is nerd zijn. Blijf Maken. (Of wordt, bijvoorbeeld, cultuurhistoricus)