Zoals je misschien al wel gelzen hebt op het forum ben ik bezig met het bouwen van een robot. Niks lopends, gewoon simpel moet twee wielen voor en een zwenkwieltje achter.
Simpel... ja, dat dacht ik... Programmeren is niet het probleem, maar bij het bouwen ervan kom ik op een ander vakgebied waar ik minder van af weet: electronica.
Om beide wielen aan te drijven heb ik 2 unipolaire stappen motoren gebruikt (vanwege de precieze afstand die je kan bepalen). In eerste instantie waren ze sterk genoeg; nu echter (de robot groeit elke dag), beginnen ze kuren te vertonen: ze slaan steeds vaker een pooltje over en hebben minder trekkracht. Ik moet dus nieuwe, sterkere motoren.
Nu dacht ik aan servo- in plaats van stappen-motoren, omdat het "exact" plaatsbepalen in de loop van het project van ondergeschikt belang is geworden. Maar waar moet ik op letten? Mij zegt torque 42oz namelijk vrij weinig... koppel ja, maar wat is dat precies? en hoe bereken ik m'n benodigde trekkracht als aan de hand van het gewicht van m'n robot?
Alvast bedankt voor het beantwoorden van m'n vraag.
***PS. Omdat ik toch mijn stappenmotoren wilde gebruiken dacht ik om deze bovenop de robot te zetten; staaf eraan, met aan het uiteinde een sonar sensor, zodat hij de omgeving helemaal kan "zien". Is dit mogelijk of krijg ik het probleem dat de metingen niet kloppen vanwege de combinatie van draaien/echo meten? Zou ik dan eventueel met het doppler-effect kunnen/moeten werken om dit op te lossen of denk ik nu verkeerd?*** (Edit: Of beter Ir-sensor nemen?)
Je zou bijvoorbeeld Futaba S3003 servo's kunnen nemen. Met wat knutselwerk zijn ze goed te gebruiken als aandrijvende motoren. Omdat je het nog een "beetje" moet leren: http://duteela.et.tudelft.nl/~elca/XilinxTutor/Plabopdrachten.html

Dat zal vast wel lukken nu!
Sterk aan te raden is om je stappenmotoren te vervangen voor servo's of dc motortjes met encoder... die vreten minder stroom... dat kan overigens ook de reden zijn dat je steppers minder goed werken? wel regelmatig de batterijtjes ververst?
een 'standaard' servo heeft een trekkracht van zo'n 2,5 a 3 kg/cm volgens algemene specificaties... (correct me if I'm wrong)
hebben je steppers een transmissie(ofwel vertraging) of zitten de wieltjes practisch direct op de as? je levert iets in op snelheid, maar wint weer terug op trekkracht.
vandaar servo's en gewone geared motortjes. Als je servo's gebruikt zal je ze wel voor kontinu draaien moeten modificeren en is plaatsbepalen niet zo makkelijk meer mogelijk.. Vandaar een terugkoppelijk op de wielen middels encoders...
gr madthijs
@ Mr. M; ik ben inderdaad nog een beginner op dit gebied ja, dat mag ook gezegd worden
Die link van jou is daarom ook zeer bruikbaar! denk je dat 2 Futaba S3003 motoren een robot van ongeveer 4 kilo kan trekken? Als je denkt dat 't kan, ga ik ze meteen bestellen.
@ Madthijs; wat bedoel je precies met een encoder? Een soort driver om makkelijker aan te sluiten op de microcontroller?
Wat betreft de spanning: ik heb gebruik nu een externe voeding dus Voltjes/Amperetjes genoeg.
Wat wilt die "2,5 a 3 kg/cm" zeggen trouwens? Wat kan ik met zo'n trekkracht?
En is een servo niet gewoon een dc motor met tandwieltjes in een behuizing? ff kort door de bocht (of TE kort?)
Op 20 maart 2007 20:19:34 schreef XQlusive:
En is een servo niet gewoon een dc motor met tandwieltjes in een behuizing? ff kort door de bocht (of TE kort?)
Een servomotor is in principe iedere motor met terugkoppeling en een vorm van asbesturing. In de industrie zijn het meestal AC motoren.
iets te kort door de bocht dus
maar een duidelijke uitleg GJ, bedankt.
Het project voor school had eigenlijk de nadruk op het programmeren, maar er komt veel meer bij kijken dan van te voren was voorzien. Niet erg hoor, ik leer er veel van en het is nog leuk ook; maar dan krab je toch eens achter je oor als student met alleen iets meer dan basis VWO kennis qua electronica. Veel ervaring opdoen is eigenlijk DE manier ben ik al wel achter...
Op 20 maart 2007 20:19:34 schreef XQlusive:
@ Mr. M; ik ben inderdaad nog een beginner op dit gebied ja, dat mag ook gezegd wordenDie link van jou is daarom ook zeer bruikbaar! denk je dat 2 Futaba S3003 motoren een robot van ongeveer 4 kilo kan trekken? Als je denkt dat 't kan, ga ik ze meteen bestellen.
@ Madthijs; wat bedoel je precies met een encoder? Een soort driver om makkelijker aan te sluiten op de microcontroller?
Wat betreft de spanning: ik heb gebruik nu een externe voeding dus Voltjes/Amperetjes genoeg.Wat wilt die "2,5 a 3 kg/cm" zeggen trouwens? Wat kan ik met zo'n trekkracht?
En is een servo niet gewoon een dc motor met tandwieltjes in een behuizing? ff kort door de bocht (of TE kort?)
Lijkt me wat stevig, maar er zijn vast grotere modellen te vinden die ook aanpasbaar zijn zodat ze 360 graden gaan roteren.
Die paar kilo/cm is de stelkracht van de (modelbouw)servo.
in theorie zou de servo het dus voorelkaar kunnen krijgen om die paar kilo te kunnen trekken met een arm van 1 cm tov het midden van de as. nooit geprobeerd of ze dat ook echt kunnen.
met encoder bedoel ik een apparaatje, wat bijvroobeeld middels een infrarood sensortje een puls afgeeft per omwenteling, of nog nouwkeuriger, een aantal pulsen per omwenteling. je hebt ze in veel verschillende uitvoeringen.
voorbeeld: scrol wieltje in je muis gebruikt een soort sensor die een lichtstraaltje onderbreekt waardoor de sensor even geen licht ziet (lichtsluisje). Ook heb je systeempjes die een soort reflector hebben met wit/zilver en zwarte streepjes, die een refelectiesensortje 'leest' en afhankelijk daarvan pulsjes uitpoept.
Ook zijn er encoders die je op een as plaatst, welke 2 pulsen geeft die in fase met elkaar zijn, ook wel 'rotory encoders' daarmee is het ook makkelijk mogelijk om de richting te bepalen.
een modelbouwservo is inderdaad een dc motortje met vertraging, als je de electronica die erin zit buiten beschouwing laat. de electronica die er in zit (ongemodificeerd) zorgt ervoor de je door een puls-breedte-gemoduleerd signaal, een hoekverdraaiing in kan stellen. als je een servo modificeerd, (je maakt hem eigenlijk blind, en haald de eindstops eruit) kan je door een pwm signaal aan te bieden (pulse width modulation) vrij simpel de richting van de motor sturen.
als je ze toch hebt liggen.. een h-brug vind ik persoonlijk net zo makkelijk.
gr madthijs
de infrarood sensortjes kunnen dit oveirgens ook, als een 2de ontvanger (wat in een muis ook gebeurt) gebruikt word, en in het 2de geval een 2de reflectiesensortje.
het voordeel van de infrarood sensortjes is, dat ze makkelijk te bouwen zijn, en alleen optisch contact maken met het wiel. enig nadeel is dat je een vrij apart patroontje op je wieltjes krijgt, maar dat is puur cosmetisch.
Op 22 maart 2007 19:32:02 schreef madthijs:
met encoder bedoel ik een apparaatje, wat bijvroobeeld middels een infrarood sensortje een puls afgeeft per omwenteling, of nog nouwkeuriger, een aantal pulsen per omwenteling.
Een encoder op een servo geeft meer dan 1 puls per omwenteling. Een AC servo zou nl niet te besturen zijn. De encoders met het laagste pulstal geven er altijd nog 2x2048 per omwenteling. Dat betekend in de besturing dus een oplossend vermogen van 8192 delen/omw.
De motoren die ik meestal gebruik hebben 2x4096 pulsen per omwenteling: een oplossend vermogen van 16384 delen/omwenteling.
Er zijn ook servo's (meestal DC) die gewoon een tacho gebruiken voor terugkoppeling.
Een andere methode van terugkoppelen is een resolver, alhoewel die (net als DC motoren en tacho's) steeds minder in de mode raken.
[Bericht gewijzigd door GJ_ op ]
Fantomaz
Ik moet hier weer vaker komen... Wat kun je zo'n forum als deze gaan missen. :-)
Hoe zit dat dan met de PWM? Pulse With Modulation?
Die PWM bepaalt de hoek van de servo arm. Maar op een gegeven moment zit hij -normaliter- op zijn max.
Als deze gedeblokkeerd is, zal hij inderdaad door kunnen lopen. Maar met welke waarden, pwm gezien...?
Gewoon pulsen van 1ms loopt ie rechtsom, met pulsen van 2ms loopt ie linksom.
Als je de stops eruithaald en de potmeter vervangt door twee gelijke weerstanden blijft ie altijd draaien tot je een pulslengte geeft van ongeveer 1,5ms.
Ik ben na wat zoeken naar informatie over H-bruggen er achter gekomen dat deze inderdaad wel heel makkelijk werken! Heb er meteen 1 gemaakt en in combinatie met m'n PIC en een dc motor waar ik een vertraging voor heb gemaakt, heb ik toch nog een makkelijk te besturen/sterke aandrijving gekregen. Bedankt voor de tips!
Morgen een tweede maken en in m'n frame maken, hopenlijk een testrit zonder al teveel problemen en dan kan het echte programmeren beginnen! 
Zoals ik hierboven al vermeld had, ga ik nu 1 van m'n stapenmotoren gebruiken om in combinatie met een ir-sensor te bepalen waar een voorwerp zich bevindt. De IR-sensor die ik ga gebruiken is de volgende:
Datasheet
De aansluiting zou simpel zijn: 1 draad aan de -, 1 draad aan +5V en de laatse aan een input poort van m'n microcontroller.
Heeft hier iemand ervaring mee en zo ja zou hij/zij me dan uit willen/kunnen leggen hoe ik de waarde uitlees? Ik snap dat het een spanning is, maar hoe zet ik dit om naar cm? Is dit lineair?
De code welke ik gebruik om de poorten uit te lezen is in C:
int result;
while(1) {
Delay10TCYx(5);
ADCON0bits.GO = 1;
while(ADCON0bits.GO == 1);
result = ADRESH;
PORTBbits.RB7 = result;
}
De code werkt, maar ik weet niet precies wat ik doe en waarom en dat is toch wel belangrijk lijkt me zo. Ik wil bijvoorbeeld zeggen dat als de waarde van de sensor onder de 30 cm is, de robot een uitwijk actie moet uitvoeren. Kan ik dan zeggen:
if (result <= x) {}
//waar x een nader te bepalen waarde is wat overeenkomt met 30 cm.
Hopelijk is m'n verhaal duidelijk en kan iemand me helpen. Alvast bedankt.
(Misschien hoort dit laatste eigenlijk in een ander topic thuis...?)
Niemand een idee hoe ik de analoge poorten zou aan kunnen roepen? Ik loop nu ehct ontzettend vast :$
while(1) {
for (i=0; i<1; i++) {
ADCON0 = 0x10; //Channel 0 and 1, not started, ADC ON
ADCON1 = 0x07; //Portconfig: AN0 analog, other i/o digital, Vref- = Vss, Vref+ = Vdd
ADCON2 = 0b00111010; //Result left justified, aq time = 20 Tad, conversion clock = Fosc/32
Delay10TCYx(5); // Delay for 50TCY
ADCON0bits.GO = 1; // Start conversion
while(ADCON0bits.GO == 1); // Wait for completion
resultLDR1 = ADRESH;
PORTBbits.RB0 = resultLDR1;
}
for (j=0; j<1; j++) {
ADCON0 = 0x01; //Channel 0 and 1, not started, ADC ON
ADCON1 = 0x07; //Portconfig: AN0 analog, other i/o digital, Vref- = Vss, Vref+ = Vdd
ADCON2 = 0b00111010; //Result left justified, aq time = 20 Tad, conversion clock = Fosc/32
Delay10TCYx(5); // Delay for 50TCY
ADCON0bits.GO = 1; // Start conversion
while(ADCON0bits.GO == 1); // Wait for completion
resultLDR2 = ADRESH;
PORTBbits.RB1 = resultLDR2;
}
}
Dit is nu m'n code, maar beide uitgangen lijken (B0 en B1) alleen te reageren op de LDR1... Iemand een idee wat ik fout doe???
@ fantomaz:
De modelbouwservo heeft een potmeter, welke meedraaid met de uitgaande as. adhv deze potmeter weet de electronica of hij in de positie staat die correspondeerd met de binnengekomen puls. Na modificatie, word of de potmeter vervangen door 2 weerstandjes, waardoor de electronica 'denkt'dat de potmeter nog in z'n middenpositie staat, of de potmeter word buiten de servo geplaatst en daar afgesteld op de midden positie.
als nu de servo pulsen ontvangt tussen 1 en 2 ms die niet 1,5 ms zijn, stuurt de electronica de motor een bepaalde kant op totdat de potmeter de juiste stand aangeeft. helaas voor het arme servo'tje zal de potmeter dit (als het goed is) nooit doen. Daarom blijft het motortje de gewenste richting in draaien.
@xqlusive:
kijk eens op pagina 3 van je datasheet. daar staat een grafiekje met afstand/voltage.
De laatste code ging over het vergelijken van 2 waardes van sensoren. Ik blij hier problemen mee houden: op de 1 of andere reden krijg ik het niet voor elkaar een specifieke poort uit te lezen...
Ik ben me bewust van de grafiek in de datasheet, maar heb geen idee hoe deze waarde uitgelezen zal worden; blijft dit een waarde tussen 0,4 en 2,5 of wordt dit omgezet naar een waarde tot 1024 (dmv de AD converter)?
Die word omgezet naar een digitale waarde.
in de datasheet van je microcontroller staat hoevele bits ad converter erin zit. als het een 8 bits ad-converter is kan je je referentie voltage delen door 256, en met het voltage wat daar uit komt kan je uitrekenen hoe hoog de door jou ingelezen getallen ongeveer zullen zijn.
verstandig is, om of je sensor voor ingebruikname even te kalibreren, en een (ruime) onder en bovengrens op te slaan waartussen hij een object moet detecteren.
probeer ook je programma op te delen in deelproblemen.
schrijf bijvoorbeeld eerst een programma wat een led laat oplichten binnen een bepaalde afstand, of een poort met leds waarbij je de een led voor 'dichtbij' hebt en de led aan de andere kant voor 'veraf' met een aantal grenswaardne ertussen..
(m'n verhaaltjes zijn niet erg duidelijk :s, ik kom vanavond niet echt op de juiste woorden...sorry)
ik hoop dat je me begrijpt.
overigens, de ingelezen waarde word binair opgeslagen. (dat wil zeggen, in bits) deze waarde kan je met een decimaal, hexadecimaal, of binair getal vergelijken. als je de compiler maar verteld wat voor soort getallen stelsel je gebruikt (binair decimaal of hex)
Hexadecimale waarden geef je aan met 0x dus, 0x07 is decimaal 7 en binair 0000 0111.
binair geef je aan met 0b00000000 etc.
maar dit wist je neem ik aan al?
ja met dat binair, hexadecimaal en decimaal ben ik bekend. Ik vind het alleen wel moeilijk om het met hexadecimaal aan te duiden (nooit mee gewerkt), dus ik gebruik meestal gewoon binair.
Mijn microncontroller is de 18f4550 van microchip; datasheet micro
Wat ik hieruit haal is dat het een 10 bits ad-converter is; dus 1024?
Kan ik nu gewoon de gemeette waarden (tussen 0.4V en 2.8V) opslaan in een variabele en delen door 1024 en dit vervolgens als voorwaarde voor een vergelijking gebruiken? Dus zoiets als:
ADCON0 = 0x01;
ADCON1 = 0x07;
ADCON2 = 0b00111010;
Delay10TCYx(5);
ADCON0bits.GO = 1;
while(ADCON0bits.GO == 1);
result = ADRESH;
if ((result/1024) <= 1,5) { //1.5 V komt overeen met ongeveer 40 cm
PORTBbits.B01 = 1;
}
else {PORTBbits.B01 = 1;}
Zou dit mogelijk zijn zo? En wat moet ik aanpassen als ik nu twee sensoren uit wil lezen? heb ik 1 converter voor alle poorten of moet ik wachten tot deze "vrij" is, voordat ik hem weer gebruik. En hoe zet ik de input (ADCON0) naar bijv. poort 1? Er zijn 13 analoge poorten, kan ik dan zoiets als: ADCON0 = 0b0000000000010; zeggen?
Zoals je ziet kan ik er ook wat van om lekker door elkaar te typen... ik kon jou begrijpen, jij mij ook? 
Hej,
heb je de datasheet (het stukje adconverter) goed gelezen?
daarin staat namelijk precies beschreven wat alle registers doen.
er zit in de chip inderdaad 1 ad-converter. verder zit er een multiplexer, ofwel 'channel select' (zie register adcon0).
door in dat register de channel select bits te wijzigen, kies je een ander pinnetje waarvan je het voltage gaat lezen.
je hebt dus 3 ad control registers. met die registers kan je de adconverter instellen/activeren etc.
Ook moet je in de gaten houden, dat je ad-converter 10!!! bits gebruikt terwijl de microcontroller 8!! bits registers heeft. dus je hebt 2 registers die je moet lezen om juiste data te ontvangen.
ik ga je vanmiddag verder helpen, moet nu weg, lees nog eens goed de datasheet, en probeer te begrijpen (hoeft niet in een keer) wat er staat, leg ook de link tussen de afkortingen en de schema's)
Ik ben weer terug gegaan naar de twee LDR's, omdat ik toch het idee heb dat deze iets makkelijker te begrijpen zijn in het begin.
Eigenlijk doet ales het wel zo'n beetje, totdat ik twee sensoren gebruik en de waardes naar een specieke poort stuur (niet LATB bijv.). Ik weet ook niet of de waardes die ik krijg wel goed zijn, de ledjes knipperen veel. Ik heb de datasheet nu al 3 keer gelezen ofzo, maar ik kom er niet aan uit. Misschien doe ik iets heel stoms fout, hopenlijk kan jij me helpen...
Ik heb de LDR's zo aangesloten:
Zit hier een fout in misschien? Ik begin nu echt aan alles te twijfelen...
De code is nu voor de LDR:
int getValueLeft(void) {
ADCON0 = 0x01;
ADCON1 = 0x07;
ADCON2 = 0b00111010;
Delay10TCYx(5);
ADCON0bits.GO = 1;
while(ADCON0bits.GO == 1);
resultLDR1 = ADRESH;
return resultLDR1;
}
int getValueRight(void) {
ADCON0 = 0x00;
ADCON1 = 0x07;
ADCON2 = 0b00111010;
Delay10TCYx(5);
ADCON0bits.GO = 1;
while(ADCON0bits.GO == 1);
resultLDR2 = ADRESH;
return resultLDR2;
}
void main(void) {
TRISA = 0b11111111; // Port A is input
TRISB = 0b00000000; // Port B output
while(1) {
valueLeft = getValueLeft();
valueRight= getValueRight();
PORTBbits.RB0 = valueLeft;
PORTBbits.RB1 = valueRight;
}
}
Hej xqlusive,
Volgens mij zie je inderdaad iets over het hoofd. je leest het ADRESH register, welke inderdaad data bevat na ad-conversie. MAAR het ADRESL register, bevat ook data.
dat komt, omdat je ad-convertor 10bits breed is, en de registers van je microcontroller 8 bits.
dus heb je 2 registers nodig om de 10 bits info in op te slaan. 8 bits in het L register en 2 in het H (de laagste 2 bits van het H register worden gebruikt, voor de hoogste 2 bits van je 10 bits waarde)
je kunt uitrekenen vanaf welk voltage ADRESL vol zit, namelijk, ervanuitgaand dat je gewoon 5 volt als Vref gebruikt:
5 volt delen door 1024 maal 256, is 1,25 volt ongeveer, als het 9de bit hoog is, (BIT 0 in het ADRESH register) is je spanning 2,5 volt of hoger.
(5/1024)*512=2,5V
om een waarde te vergelijken moeten dus 2 waardes vergeleken worden..
dus, je zal 2 result waardes moeten wijzigen, en dus pointers moeten gebruiken.
madthijs bedankt voor de uitleg, ik snap nu wat ik fout doe; vond het al raar dat ik ADRESL niet gebruikte, maar had geen idee hoe ik het anders moest toevoegen (nu nog niet eigenlijk, want pointers zeggen me niet zoveel).
int getValueLeft(void) {
ADCON0 = 0x01;
ADCON1 = 0x07;
ADCON2 = 0b00111010;
Delay10TCYx(5);
ADCON0bits.GO = 1;
while(ADCON0bits.GO == 1);
resultLDR1 = ((ADRESH/1024)*256);
return resultLDR1;
}
En nu zou daar nog de waarde van ADRESL bij moeten?
resultLDR1 = resultLDR1 + ((ADRESL/1024)*256);
of moet ik dit anders doen? In ieder geval super bedankt voor je hulp, ik heb het gevoel dat ik dichter bij de oplossing kom en zie weer licht in de duisternis 
EDIT: dit laatste klopt niet... na nog een keer lezen en geloof ik het te begrijpen: je bedoelde volgens mij dat als bit 9 hoog is, de ADRESL niet meer meetelt en ik de waarde die ik uitreken door ((ADRESH/1024)*256) te doen bij 2,5 V op moet tellen? Maar hoe check ik dat poort 9 of 10 hoog is?
[Bericht gewijzigd door XQlusive op ]
Je hebt 8 bits in het adresL register, en 2 in het adresH register.. samen 10 bits. je hebt dus eigenlijk 16 bits, waarin informatie opgeslagen staat. stel ik meet 5 volt aan de ingang, dan staat er dus 0000 0011 1111 1111, waarbij adresH 0000 0011 bevat, en adresL 1111 1111. de eerste 6 nullen worden niet gebruikt, omdat de ad-converter maar 10 bits is.
is nu mijn voltage 2,5 volt staat er
0000 0010 0000 0000,
1,25 volt
0000 0001 0000 0000,
snap je dit? de eerste 8 cijfers is het ene register, en de laatste 8 het andere register. de eerste 6 nullen van de eerste 8 cijfers, (de bits 2 t/m 7 uit het adresH register) worden dus in princiepe nooit gebruikt.
wat ik probeerde aan te geven met de rekensommetjes uit m'n vorige posts is dat je zelf kunt uitrekenen welke bitwaarde overeenkomt met welk ingelezen voltage, en dus overeen komt met een bepaalde afstand.
30 cm komt overeen met (ongeveer) 2 volt.
nu, als de sensor een object op 30 cm afstand meet, zal de ad converter (ongeveer) de waarde: 0000 0001 1001 1001 aangeven...(controleer dit even!)
je kunt dit doen door het adresH regsiter te vergelijk met 0000 0000, 0000 0001, 0000 0010 of 0000 0011. dus met 0 1 2 of 3)
je zou dus kunnen zeggen dat het adresL byte een voltage bereik heeft van ongeveer 1,25 volt en dat het adresH byte de offset weergeeft.
dus, een 0 op adresH betekend dat de waarde tussen 0 en 1,25 volt kan liggen, 1 op adresH betekend dattie op 1,25 en 2,5 volt kan liggen. 2 op adresH betekend dat het voltage tussen de 2,5 en 3,75 volt kan liggen en als laatste 3 op adresH geeft aan dat het voltage tussen 3,75 en 5 volt ligt. ALS er als vref 5 volt gebruikt wordt!!!!
je kunt er voor kiezen om in de lees de analoge waarde lus van bijvoorbeeld je ldr, de 10 bits waarde te pre-scalen. dat wil zeggen, zorgen dat de waarde in 8 bits past.
dit kan je doen door 2 keer te schuivan met de bits. let wel! je meting word hierdoor onnaukeuriger, maar dat zal in jou geval niet zoveel uitmaken.
met schuiven bedoel ik: er is een waarde geconverterd naar 0000 0010 1101 1010, als ik nu schuif doe ik dit: 0000 0001 0110 1101, nogmaals schuiven en dan heb je 0000 0000 1011 0110.
Wat je ook kunt proberen is je meting ruwweg indelen in blokken, bijvoorbeeld, als de ingelezen waarde onder de n ligt word result ldr 1 0x01, ligt de waarde onder m word result 0x02 etc.
bit shiften zal je waarschijnlijk even op moeten zoeken.
overigens, zijn bitwise and or en shift instructies altijd leuk om te kunnen toepassen in uC's...
*bitn--ken* word dit ook wel genoemd.
[Bericht gewijzigd door madthijs op ]
dus als ik het goed begrijp moet ik eerst kijken wat de waarde is van ADRESH en vervolgens vanuit daar de V waarde gaan bepalen. Mocht ADRESH 0 zijn, hoef ik alleen te focussen op ADRESL.
Kan ik dan ook zeggen:
if (ADRESH == 0) {
result = (5/1024)*ADRESL
}
else if (ADRESH == 1) {
result = (5/1024)*ADRESL + 256;
}
else if (ADRESH == 2) {
result = (5/1024)*ADRESL + 512;
}
else if (ADRESH == 3) {
result = (5/1024)*ADRESL + 768 // *** moet ik er dan trouwens geen 1 bij optellen om helemaal goed te zijn bedenk ik me net? ***
}
Vervolgens kan ik met result kijken wat de afstand is en dus of de robot uit moet gaan wijken?
Het kost me even wat hoofdbreeksels en misschien maka ik nog een fout, maar je uitleg is echt geweldig!
Als het zo werkt, heb ik dat bit shiften dan nog nodig?
*EDIT*
Trouwens om helemaal zeker te zijn: weet je ook hoe ik de ADCON0, ADCON1 en ADCON2 moet invullen? Doe ik dat nu goed voor poort A0 en A1 met een Vref van 5V?
int getValueRight(void) {
ADCON0 = 0x01; //dit zou A1 moeten zijn
ADCON1 = 0x07; //Vref van 5V
ADCON2 = 0b00111010; //iets met tijd :
int getValueLeft(void) {
ADCON0 = 0x00; //dit zou A0 moeten zijn
ADCON1 = 0x07; //Vref van 5V
ADCON2 = 0b00111010; //iets met tijd 
[Bericht gewijzigd door XQlusive op ]
Ik zal beginnen met adcon0
hierin zitten 6 bits waarvan 4 channel select, in de lijst eronder kan je precies zien welke combinatie eenen en nullen welk kanaal selecteerd. (chs0-chs3)
een status bit, of 'flag'(vlag) go/done welke aangeeft of de adconversie klaar is (het duurt een aantal cycles om te bepalen welk voltage op de pin staat) of dat de converter nog bezig is.
en het ad-on bit, welke de ad converter in of uitschakeld.
adcon1
heeft 6 bits, waarvan 2 de gewenste voltage referentie (Vref) kunnen instellen. default 00, wat betekend dat de Vcc en GND genomen word als referentie.
en verder, kan je voor zover ik het gelezen heb adcon2 laten zoals het is. (zoals je het nu heb, dat iets met tijd enzo) probeer te ontdekken door kleine stukjes datasheet te lezen en evt een woordenboek voor bepaalde termen te gebruiken te ontdekken hoe je dit instellen moet enzo.
zoals je ziet, klopt het commentaar bij de instellingen niet helemaal.
dit komt omdat je waarschijnlijk niet zo bekend ben met het hexadecimale stelsel.
http://nl.wikipedia.org/wiki/Hexadecimaal
hier wat info daarover, mocht je het niet zo snappen, raad ik je aan die instellingen ook binair in te vullen (0bxxxxxxxx)
de instellingen die je doet met acon0 0x00 en 0x01 is bij de 0x01 het setten van het bitje adconversie on. channel select staat bij beide op channel 0
in principe zit dit register dus zo in elkaar:
0b00ccccfo waarbij de c's staan voor channel f voor flag en o voor on.
Madthijs echt nogmaals bedankt dat je zoveel tijd en moeite in je uitleg wilt steken: ik snap nu tenminste waar ik mee bezig ben! Ik snap nu zelfs hoe je in 't hexadecimale stelsel telt (niet dat het ehct heel moeilijk is, maar toch
je moet 't ff weten he). Weet je trouwens wat het voordeel is om op deze manier te tellen? Octaal kan ik de logica nog van zien ivm de bits, maar bij hexadecimaal zie ik het niet zo.
Mara dat ter zijde
ontzettend interesant allemaal wat ik nu aan het leren ben, maar ik merk al wel dat ik echt pas kom kijken.
Ik heb gisteravond nog geprobeerd om jouw uitleg in de praktijk te brengen; het selecteren van de afzonderlijke analoge input poorten lukt nu wel; ik weet nog niet precies wat de flag en de on doen, maar ik houd ze op 01 en het lijkt goed te werken zo.
Ik denk ook de ADRESH en ADRESL te begrijpen en m'n code ziet er nu zo uit (de benodigde functies dan) :
int getValueLeft(void) {
ADCON0 = 0b00000101; //PORT A1
ADCON1 = 0b00000000; //Vref= 5V (0x07 = 0b00000111, maar dacht het zo goed in te stellen?
ADCON2 = 0b00111010;
Delay10TCYx(5);
ADCON0bits.GO = 1;
while(ADCON0bits.GO == 1);
if (ADRESH == 0) {
resultLDR1 = ADRESL;
}
else if (ADRESH == 1) {
resultLDR1 = (ADRESL + 256);
}
else if (ADRESH == 2) {
resultLDR1 = (ADRESL + 512);
}
else if (ADRESH == 3) {
resultLDR1 = (ADRESL + 768);
}
return resultLDR1;
}
int getValueRight(void) {
ADCON0 = 0b00000001; //PORT A0
ADCON1 = 0b00000000;
ADCON2 = 0b00111010;
Delay10TCYx(5);
ADCON0bits.GO = 1;
while(ADCON0bits.GO == 1);
if (ADRESH == 0) {
resultLDR2 = ADRESL;
}
else if (ADRESH == 1) {
resultLDR2 = (ADRESL + 256);
}
else if (ADRESH == 2) {
resultLDR2 = (ADRESL + 512);
}
else if (ADRESH == 3) {
resultLDR2 = (ADRESL + 768);
}
return resultLDR2;
}
void main(void) {
TRISA = 0b11111111; // Port A is input
TRISB = 0b00000000; // Port B output
TRISC = 0b00000000;
TRISD = 0b00000000;
PORTA = 0b00000000;
PORTD = 0b00000000;
while(1) {
valueRight = getValueRight();
valueLeft = getValueLeft();
if (valueRight >= valueLeft) {
PORTBbits.RB0 = 1;
PORTBbits.RB1 = 0;
}
else if (valueRight < valueLeft) {
PORTBbits.RB1 = 1;
PORTBbits.RB0 = 0;
}
}
}
Maar waarom werkt het nu nog niet? Ik heb het gevoel dat valueRight en valueLeft de waardes niet goed op kunnen halen of zoiets? kan dat kloppen?
EDIT: *** Ik heb het werkend !!! Zelfs de Sharp Distance Sensor werkt nu zoals het moet. De fout? Ik heb ADCON1 en ADCON2 in main gedefineerd en later niet meer aangeroepen. Daarbij komt ook nog dat ik ADCON2 van 0b00111010; naar 0b10111010; veranderd heb. Was iets met left or right-justify.
Zonder jou was dit niet gelukt Madthijs!