Een aantal jaar geleden heb ik een RC transmitter met receiver gekocht. Toen kon ik er nog niet veel mee dus hij is vrijwel direct in de kast beland.
Een maand of 2-3 geleden heb ik een Arduino gekocht om programmeren te leren en zelf kleine projectjes te maken.
Toen ik een bestuurbare auto wou maken met mijn Arduino en een bluetooth module kwam ik er echter achter dat het bereik van zo'n bluetooth module wel heel erg klein is. Hierom heb ik dus mijn RC spullen weer uit de kast gepakt. Hieraan kunnen in principe 3 servo's of motoren. Echter zijn de RC motoren vrijwel altijd met 3 snoeren (net zoals bij een servo, dus via PWM). Ik heb alleen motoren liggen met 2 aansluit punten. Hiervoor wou ik dus mijn Arduino gaan gebruiken. Zodra de Arduino een input krijgt (in PWM) wil ik een andere poort een output geven, mijn vraag is dan ook, hoe kan ik een binnenkomend pulse width modulation signaal herkennen, is hier misschien een speciale functie voor? En zo niet, enige andere ideeën hoe ik dit kan oplossen?
ReniervS:
. Zodra de Arduino een input krijgt (in PWM) wil ik een andere poort een output geven, mijn vraag is dan ook, hoe kan ik een binnenkomend pulse width modulation signaal herkennen, is hier misschien een speciale functie voor? En zo niet, enige andere ideeën hoe ik dit kan oplossen?
Ik neem aan dat het PWM signaal een constante vaste amplitude heeft. Als je een PWM signaal door een laagdoorlaatfilter stuurt (RC filter) dan maak je van het PWM signaal een gelijkspanning die varieert tussen 0 en de piekspanning van het PWM signaal. Dit gelijkspanninkje kun je dan meten op een analoge ingang van de arduino.
De RC kan alleen maar servo signalen versturen.
Dat betekent dat er een soort van PWM gebruikt word (is niet helemaal hetzelfde).
PWM is Puls Breedte Modulatie, een servo word bestuurd door een Puls Duur Modulatie. Bijna hetzelfde, maar net niet.
Nul (midden) is een pulsje dat 1.5 mS duurt.
Maximaal rechts is 2 mS, maximaal links is 1 mS.
Deze pulsen worden in verschillende herhalingsfrequenties gestuurd, veel genoemd is om de 20 mS.
Dit ligt aan het ontwerp en fabrikant van de RC.
Maar dat is dus het verschil tussen PWM, dat continu herhaald word, en dit signaal dat dus om de n tijd verstuurd word en waar dus een relatief grote afstand tussen puls en pauze is.
Je kunt dit soort pulsen meten met een PulseIn() (klik !) commando.
Wellicht is dat iets teveel van het goede als je nog maar net begonnen bent, maar lees die pagina eens door zou ik zeggen.
Je moet wel even opletten of dit commando niet de timers herconfigureert en de PWM functie verstoort (ik weet het niet).
De servo library gebruikt (misbruikt ?) PWM om de signalen te genereren, dus het zou me niets verbazen als dat hier elkaar ook zou beïnvloeden.
Helaas is het me na een avond proberen niet gelukt het werkend te krijgen volgens jou route. Wel heb ik onderhand een andere manier gevonden waarmee het gaat lukken.
Bedankt voor de tijd en moeite!
Allereerst bedankt voor het welkom heten.
Na de pagina van PulseIn() door te hebben gelezen heb ik het ook maar direct uit geprobeerd. Ik heb hem in eerste instantie op de seriële monitor getest en dat leek perfect te werken! De rest van het programma heb ik ook al uit gedacht en dat lijkt geen problemen te gaan geven.
Enorm bedankt voor je hulp!
servo's gebruiken geen pwm.
Pulse in kan je gebruiken maar dat zet je arduino in blokeer mode (je sketch doet niks meer dan wachten op een puls) en dat is misschien geen probleem voor 1 kanaal maar voor 4 is dat echt niet meer te doen.
Wat je nodi hebt is een interrupt. Interrupt is niet zo makkelijk. Daarom kan je ook best werken met een library
Kijk eens naar ArduinoLibraries/RCLib at master · jantje/ArduinoLibraries · GitHub
Kijk, das nou het mooie van zo'n forum waar iedereen kan deelnemen aan de gesprekken.
Ik had geen idee dat PulseIn een blokkerende code genereert, zelf nog niet mee gespeeld, alleen van gehoord.
MAS3:
Kijk, das nou het mooie van zo'n forum waar iedereen kan deelnemen aan de gesprekken.
Ik had geen idee dat PulseIn een blokkerende code genereert, zelf nog niet mee gespeeld, alleen van gehoord.
Kijk eens aan, wat een top hulp!
Zover ik het nu begrijp zou het (nog) geen problemen geven als mijn code blokkeert tenzij ik het wil gaan uitbreiden. Hierom denk ik dat ik toch maar even bij de library ga kijken die bijgevoegd is.
Ontzettend bedankt voor jullie hulp!
Tja, dat krijg je als je na een "vrije dag" na 20:00 uur thuis komt van het werk en dan laat nog even op internet gaat kijken.
Ik had alleen die reference page en informatie over hoe het ook weer precies zat met servoservosturing opgezocht, maar die reference niet helemaal gelezen...
Vandaag weer een vrije dag, dus zal straks na het werk die laatste link eens gaan bekijken.
Duane is de auteur van die stukjes blog waar ik naar verwees. Ik vind dat hij het heel goed uitlegt.
Er is heel wat "misverstand" rond rc en servo's. PWM versus PPM is daar 1 van.
De library waar ik naar verwees heb ik gemaakt op basis van de code die Duane op de blog geeft maar legt er een laagje rond.
Kijk zeker naar het bijgesloten voorbeeld.
Indien je de arduino eclipse plugin gebruikt moet je de .ino file naar .cpp hernoemen of het zal niet werken omdat de include volgorde heel belangrijk is.
Hmm, nu wel even de reference over PulseIn gelezen, en moet zeggen dat ik uit die tekst niet direct haal dat er daar geblokkeerd word.
Ik neem wel direct van je aan dat dat zo is, en het daarom niet bepaald een goed idee is om dit te gebruiken (zoals velen al weten vind ik het altijd een slecht idee blokkerende code te gebruiken als dat niet hoeft).
In de tekst staat wel beschreven dat er gewacht word tot de puls volledig waargenomen is, maar niet dat dat wachten betekent dat er verder iets meer mogelijk is.
Dat is wel noodzakelijk als je heel nauwkeurig de pulslengte wil kunnen registreren, en dus ook wel begrijpelijk.
Eigenlijk vind ik dat dit daarom in dei reference page wel genoemd zou moeten worden, bij wijze van waarschuwing.
MAS3:
Hmm, nu wel even de reference over PulseIn gelezen, en moet zeggen dat ik uit die tekst niet direct haal dat er daar geblokkeerd word.
Ik haal dat uit.
...waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW...
Omdat PPM aan 50 hrtz werkt heb je maar elke 20ms een pulse. Daar de pulsen op alle kanalen tergelijk komen heb je dus bij 5 kanalen minimaal 80ms (420ms) of maximaal 100ms (520ms)nodig.
En hier de code
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
* or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
* to 3 minutes in length, but must be called at least a few dozen microseconds
* before the start of the pulse. */
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
// cache the port and bit of the pin in order to speed up the
// pulse width measuring loop and achieve finer resolution. calling
// digitalRead() instead yields much coarser resolution.
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
uint8_t stateMask = (state ? bit : 0);
unsigned long width = 0; // keep initialization out of time critical area
// convert the timeout from microseconds to a number of times through
// the initial loop; it takes 16 clock cycles per iteration.
unsigned long numloops = 0;
unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;
// wait for any previous pulse to end
while ((*portInputRegister(port) & bit) == stateMask)
if (numloops++ == maxloops)
return 0;
// wait for the pulse to start
while ((*portInputRegister(port) & bit) != stateMask)
if (numloops++ == maxloops)
return 0;
// wait for the pulse to stop
while ((*portInputRegister(port) & bit) == stateMask) {
if (numloops++ == maxloops)
return 0;
width++;
}
// convert the reading to microseconds. The loop has been determined
// to be 20 clock cycles long and have about 16 clocks between the edge
// and the start of the loop. There will be some error introduced by
// the interrupt handlers.
return clockCyclesToMicroseconds(width * 21 + 16);
}
Waaruit ik opmerk dat de code eigenlijk is:
...waits for the pin to go LOW,waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW...
je kunt een servo gewoon direct aansluiten op een arduino hoor, dan komt er een tijdspuls uit.
zie servo library.
je kunt ook een servo ontvangen via je RC en die naar een analoge waarde omzetten. en dat gaat het beste met PulseIn, wel even aan denken dat er dan even niets gebeurt met je programma. maar dat is vaak niet zo van belang.
die analoge waarde kun je dan weer vertalen naar een echte PWM om de motor aan te sturen.
ja hoor, mas3.
een servo is geen pwm motor, en als er maar twee draden uit een otor komen dan is het dus een gewone DC motor en die heeft dus PWM nodig, maar de zender geeft een tijdpuls uit en die moet vertaald worden.
shooter:
ja hoor, mas3.
een servo is geen pwm motor, en als er maar twee draden uit een otor komen dan is het dus een gewone DC motor en die heeft dus PWM nodig, maar de zender geeft een tijdpuls uit en die moet vertaald worden.
Met pulseIn maak je van je tijd modulatie signaal geen analoog signaal, maar je kunt wel de waarde bepalen.
Er is echter een heel goede reden gegeven om PulseIn niet te gebruiken.
Ik stelde de vraag omdat je niets anders vertelde als wat er eerder al in de thread besproken was.
Maar goed.
We hebben ReniervS dit jaar nog niet gehoord.
Hoe gaat het nu met de sketch, ben je al verder geraakt, ReniervS ?