Ik ben momenteel bezig met het maken van een lijnvolger. Ik ben al een heel eind met mijn onderzoek ernaar hoe het werkt en hoe je het maakt. Ik gebruik een Atmega8 als microcontroller. Ik gebruik een L298N om de motroen te besturen.
Nu is het enige wat mij nog tegenhoudt van het uitvoeren van mijn plan: de aandrijving. Ik wil zeg maar twee DC-motoren naast elkaar zetten en door middel van "differential control" sturen. Als ik bijvoorbeeld wil dat de robot naar links gaat dan gaat de linker motor naar achter draaien en de rechter naar voren. Ik gebruik PWM om de motoren aan te sturen. En hier zit het probleem ook. De Atmega8 heeft maar drie PWM-pennen en ik heb er vier (vier inputs op de L298N) nodig, als ik de richting van de twee motoren los van elkaar wil kunnen aansturen.
Een oplossing zou kunnen zijn om in plaats van de vier inputs de twee enables van PWM te voorzien, maar dit heb ik uitgetest en dit neemt toch een deel van de kracht van de motor weg.
Iemand een idee hoe ik dit kan laten werken? Ik zat te denken aan misschien nog wat losse en-poortjes te kopen, maar mag je PWM signaal parallel aansluiten, is dat wel goed voor de sterkte van het signaal? Ik zou dan maar twee-PWM kanalen nodig hebben. Maar misschien zijn er ook nog wel betere manieren om dit te regelen?
Gebruik een paar AND poortjes waar je stuursignaal + PWM opzet. Dan heb je nog maar twee PWM signalen nodig. Als je je PWM interrupt driven maakt kan je denk ik de AND zelfs in de AVR afhandelen.
Wouter van Ooijen
Wouter van Ooijen: VOTI webwinkel, docent HvU (Technische Informatica); C++ on mictrocontrollers blog
Op 12 oktober 2009 19:17:38 schreef ulquiorra_cifer:
Een oplossing zou kunnen zijn om in plaats van de vier inputs de twee enables van PWM te voorzien, maar dit heb ik uitgetest en dit neemt toch een deel van de kracht van de motor weg.
Volgens mij doe je dan toch iets fout, dat is de normale manier om zoiets te doen.
Op 12 oktober 2009 19:26:07 schreef _Danny_:
Gebruik een paar AND poortjes waar je stuursignaal + PWM opzet. Dan heb je nog maar twee PWM signalen nodig. Als je je PWM interrupt driven maakt kan je denk ik de AND zelfs in de AVR afhandelen.
Oké, mooi dat ik in de goede richting zat. Ik wil het liefste nog even geen interrupts gebruiken, omdat ik nog maar net begonnen ben.
In ieder geval bedankt voor het snelle antwoord. Wat is een goede AND-poort? 74HC00?
@Wouter: het zou kunnen, maar iemand op tweakers.net had precies hetzelfde probleem. Het werkte trouwens wel met enable, maar ik merkte toch een degelijk snelheidsverschil. Ik gebruik correct phase pwm met een 8bit schaal.
Op 12 oktober 2009 19:32:39 schreef Wouter van Ooijen:
[...]Volgens mij doe je dan toch iets fout, dat is de normale manier om zoiets te doen.
Ik heb dezelfde ervaring met een L293D, de motor verliest koppel zodra je PWM op de enable lijn zet. Dat rijmt niet met wat ik begrijp van de datasheets van de 293 en 298, bij gelijke inputs doen die een fast brake terwijl enable laag een slow brake (free running) doet. Dat laatste lijkt mij wat je wilt?
Nu ik die datasheets zit te bekijken bedenk ik me dat ik in mijn setup geen diodes heb gebruikt terwijl die in vrijwel alle schema's in de sheets gebruikt worden. Kan dat de reden zijn dat PWM op de enable ljn niet werkt?
@ulquiorra_cifer: De 74HC00 is NAND (not AND) een 08 is makkelijker denk ik.
Ik heb geen idee wat slow brake of fast brake inhoudt. Maar zoals Wouter al zei zou het via enable moeten werken. Dus misschien dat iemand anders er meer van weet.
Edit: is een slow brake zeg maar dat je hem laat uitrollen en een fast brake dat voor en achter dezelfde krachten werken en daarom je motor stopgaat?
[Bericht gewijzigd door Henry S. op (53%)]
Hallo.
Ik snap het probleem ook niet, je pwm gewoon op je EN_A en EN_B laten staan en sturen met IN_1, IN_2, IN_3, IN_4.
Dat moet geen enkel probleem zijn, doe het zelf ook altijd zo.
Maar dan valt er dus kracht weg van het motortje.
Edit: natuurlijk niet een heel groot probleem, als hij maar snel genoeg gaat.
[Bericht gewijzigd door Henry S. op (53%)]
Daar ben ik helaas niet zo goed in (ben hier een maandje mee bezig en geen ervaring hiervoor met iets anders gehad), maar ik gebruik correct phase pwm en dan zet ik OCR2 op 255, dan draait hij in ieder geval wel goed. Maar zoals gezegd, PWM op input en hij draait duidelijk sneller. Bij frequenties waarop mijn motor normaal niet wil gaan draaien, draait hij wel als de PWM op de input staat.
Ik kan wel even het berekeningetje opzoeken, zodat ik de frequentie precies kan zeggen.
Edit: 15,686Hz, als ik het goed heb. (Prescaler = 1, Clockspeed = 8Mhz)
[Bericht gewijzigd door Henry S. op (11%)]
OKE, ik zie dat je een atmega gebruikt, niets mis mee maar daar heb ik geen ervaring mee.
Zelf zet ik de pwm frequentie altijd op 15KHz, 15000Hz dus en dat werkt goed.
Oke, dat heb ik dus ook.
Ik ga denk ik toch en-poorten gebruiken voor PWM op de input poorten, omdat ik het idee heb dat de motor dan toch ook net iets stabieler draaide en sowieso sneller.
Als iemand nog suggesties mocht hebben waarom hij slechter werkt met PWM op enable, dan houd ik me aanbevolen.
[Bericht gewijzigd door Henry S. op (31%)]
Ik zit weer met een probleem. Om de photodiodes uit te kunnen lezen gebruik ik een comparator (LM339N). Nu probeer ik die met een testopstelling werkend te krijgen, maar dat lukt niet.
Ik heb gewoon VCC aan 5 volt gehangen en Ground aan ground. Vervolgens op "-" 5 volt met een 10 kOhm weerstand gehangen en op "+" gewoon 5 volt. Aan de output heb ik een ledje gehangen, maar ik krijg hem dus niet werkend. Ik heb wel iets gelezen van open collector uitgangen en dat ik dus een pull-up moet gebruiken. Ik heb dat gedaan, maar ik weet niet zeker of die klopt. Ik heb de output verbonden aan een ledje naar ground en aan 5v met een 10 kOhm weerstand.
Iemand enig idee wat er fout gaat? Ik heb echt het idee dat de LM339N niet werkt.
Waarom PWM op de enable-pin? Dat is voor niets nodig. Het enable-signaal gebruik je in principe enkel om het ic af te schakelen.
Voor 2 motoren heb je maar 2 PWM signalen nodig, nl. 1 per motor. Van de 2 ingangen die je gebruikt per motor, kun je 1 ingang gebruiken om de richting te bepalen, hierop is geen PWM signaal nodig. Als je de motor bv. 70% vooruit wilt laten draaien, en je motor is aangesloten op OUT_1 en OUT_2, dan zet je op IN_1 een 0 en op IN_2 een 70% hoog PWM-signaal. Voor 70% achteruit zet je dan op IN_1 een hoog niveau en op IN_2 een 70% LAAG PWM-signaal (wat natuurlijk hetzelfde is als een 30% hoog PWM-signaal).
Oke, beetje late reactie.. Maar goed:
Waarom PWM op de enable-pin? Dat is voor niets nodig. Het enable-signaal gebruik je in principe enkel om het ic af te schakelen.
Voor 2 motoren heb je maar 2 PWM signalen nodig, nl. 1 per motor. Van de 2 ingangen die je gebruikt per motor, kun je 1 ingang gebruiken om de richting te bepalen, hierop is geen PWM signaal nodig. Als je de motor bv. 70% vooruit wilt laten draaien, en je motor is aangesloten op OUT_1 en OUT_2, dan zet je op IN_1 een 0 en op IN_2 een 70% hoog PWM-signaal. Voor 70% achteruit zet je dan op IN_1 een hoog niveau en op IN_2 een 70% LAAG PWM-signaal (wat natuurlijk hetzelfde is als een 30% hoog PWM-signaal).
Is het dan voor vooruit:
IN_1 = 0, PWM = 200
En voor achteruit:
IN_1 = 1, PWM = 55
Het PWM kanaal kan van 0 tot 255.
Ik ben een hele grote noob, dus ik kan het helemaal fout hebben. Maar klopt dit zeg maar met percentages hoog en laag waar jij het over had?
Dat zijn niet helemaal de juiste waarden voor de 70/30 verhouding, dan kom je op:
Vooruit, 70% van de snelheid
IN_1 = 0, PWM = 178
(70% van 255 = 255 * 70/100 = 178 naar beneden afgerond)
Achetruit, 70% van de snelheid
IN_1 = 1, PWM = 76
(30% van 255 = 255 * 30/100 = 76 naar beneden afgerond)
Jou snelheid komt op circa 78%. De verhouding klopt wel (even snel achteruit als vooruit).
Dat die waarden niet helemaal klopten voor 70/30, was ik me van bewust. Had ik er inderdaad even bij moeten zetten.
Bij een PWM van 255, wordt er dan gewoon een constante 12volt op bijv. de motor gezet zonder PWM?
[Bericht gewijzigd door Henry S. op (54%)]
Inderdaad, bij een duty-cycle van 100% zou de PWM-generator een constant hoge uitgang moeten hebben.
Ik heb een tijdje geleden de code geschreven (vrijwel direct na jullie laatste responses), maar ik zit nu nog steeds op de onderdelen te wachten. Daarom even de vraag of iemand mijn scriptje kan beoordelen, zodat ik zeker weet dat daar geen grote fouten in zitten.
Hier is de code:
#include <avr/io.h>
#define LEFT_SENSOR PINB & (1 << PINB6)
#define RIGHT_SENSOR PINB & (1 << PINB7)
#define MOTOR_PWM_LEFT OCR1A
#define MOTOR_PWM_RIGHT OCR1B
void left(void) {
MOTOR_PWM_LEFT = 200;
PORTB |= ~(1 << PB3);//PORTB3 laag
MOTOR_PWM_RIGHT = 55;
PORTB |= (1 << PB4);
}
void right(void) {
MOTOR_PWM_LEFT = 55;
PORTB |= (1 << PB3);
MOTOR_PWM_RIGHT = 200;
PORTB |= ~(1 << PB4);
}
void straight(void) {
MOTOR_PWM_LEFT = 200;
PORTB |= ~(1 << PB3);
MOTOR_PWM_RIGHT = 200;
PORTB |= ~(1 << PB4);
}
int main()
{
TCCR1B = 0; // Turn all PWM whilst setting up
TCCR1A = 0;
// Select 8 bit phase correct with TOP=255
TCCR1A |= (1<<WGM10);
// Select prescaler = 1
TCCR1B |= (1<<CS10);
// Turn on the PWM channel using non-inverting mode
TCCR1A |= (1<<COM1A1) | (1 << COM1B1);
//Poorten initialiseren
DDRB |= (1 << DDB1) | (1 << DDB2) | (1 << DDB3) | (1 << DDB4) | ~(1 << LEFT_SENSOR) | ~(1 << RIGHT_SENSOR);
while(1) {
while(!LEFT_SENSOR && RIGHT_SENSOR) {
right();
}
while(LEFT_SENSOR && !RIGHT_SENSOR) {
left();
}
while(LEFT_SENSOR && RIGHT_SENSOR) {
straight();
}
}
return 0;
}
Uitleg:
De sensors zitten aangesloten op een LM324 en die geeft een hoog signaal bij een zwarte lijn en een lage bij een hoge lijn. De pinnnen LEFT_SENSOR en RIGHT_SENSOR zijn hiervoor op input gezet.
PB3 en PB4 worden gebruikt om achteruit en vooruit te kunnen bepalen op de IN-poortjes van de H-brug. Als deze hoog zijn dan gaat het wiel achteruit.
De PWM waarde die ik heb gebruikt (200) is hier nog even fictief, omdat ik nog niet heb kunnen uitproberen bij welke waarde de motors goed draaien en niet te snel gaan.
