Don't ad-block us - support your favorite websites. We have safe, unobstrusive, robotics related ads that you actually want to see - see here for more.
0 Members and 1 Guest are viewing this topic.
I'll use the Board Designer to create a board so you guys can program it using WebbotLib.
5. A 3v3 regulator would be nice as many sensors are now 3v3
void Forward(){ digitalWrite(Motor_1_Dir, LOW); // forward digitalWrite(Motor_2_Dir, LOW); // forward analogWrite(Motor_1_PWM, speed1); // analogWrite(Motor_2_PWM, speed2); // return;}void Reverse(){ digitalWrite(Motor_1_Dir, HIGH); // reverse digitalWrite(Motor_2_Dir, HIGH); // reverse analogWrite(Motor_1_PWM, 255-speed1); // analogWrite(Motor_2_PWM, 255-speed2); // return;}void Right(){ digitalWrite(Motor_1_Dir, HIGH); // reverse digitalWrite(Motor_2_Dir, LOW); // forward analogWrite(Motor_1_PWM, 255-speed1); // analogWrite(Motor_2_PWM, speed2); // return;}void Left(){ digitalWrite(Motor_1_Dir, LOW); // forward digitalWrite(Motor_2_Dir, HIGH); // reverse analogWrite(Motor_1_PWM, speed1); // analogWrite(Motor_2_PWM, 255-speed2); // return;}void Stop(){ digitalWrite(Motor_1_PWM, LOW); digitalWrite(Motor_1_Dir, LOW); digitalWrite(Motor_2_PWM, LOW); digitalWrite(Motor_2_Dir, LOW); return;}
In sign-magnitude the controller sets the direction with the directions bits and then varies the amount of power to the motor with the PWM signal. Typically switching the ENABLE bit of the H-Bridge driver does this. The ratio of ON to OFF determines the amount of power going to the motor.There is an alternative way to drive the motor: The Enable bit is left ON all the time. One half of the H-Bridge is set forward or backwards and the PWM signal drives the other half of the bridge. The effect of this technique is that the motor is alternatively driven and shorted with the ratio set by the PWM signal.
// Bot4Julia, a simple Start Here style robot, made with 2 CDs,// 2 GM17 motors and wheels, one servo, one SeeedStudio US sensor,// one battery box, one uBotino board//// uBotino board pinout://// uBotino Funct Arduino ATmega168 Arduino Funct uBotino// +-----\/----+// Reset 1| PC6 PC5 |28 D19 A5 SCL RightBumper// Rx D0 2| PD0 PC4 |27 D18 A4 SDA LeftBumper// Tx D1 3| PD1 PC3 |26 D17 A3 // Int0 D2 4| PD2 PC2 |25 D16 A2 // Int1 D3 5| PD3 PC1 |24 D15 A1 IR sensor// Spk D4 6| PD4 PC0 |23 D14 A0 Ping// 7| VCC GND |22 // 8| GND AREF |21 // Xtal 9| PB6 AVCC |20 // Xtal 10| PB7 PB5 |19 D13 SCK LED // M1A OC0B D5 11| PD5 PB4 |18 D12 MISO // M2A OC0A D6 12| PD6 PB3 |17 D11 OC2A MOSI // M2B D7 13| PD7 PB2 |16 D10 OC1B // M1B D8 14| PB0 PB1 |15 D 9 OC1A Pan servo// +-----------+//#include <SoftwareServo.h>#include <Speaker.h>//Inputs/outputs//#define Encoder_1_ChA 2 // digital pin 2 // Right Encoder//#define Encoder_2_ChA 3 // digital pin 3 // Left Encoder#define Motor_1_PWM 5 // digital pin 5 // Right Motor#define Motor_1_Dir 8 // digital pin 8#define Motor_2_PWM 6 // digital pin 6 // Left Motor#define Motor_2_Dir 7 // digital pin 7#define PingPin 14 // digital pin 14 (analog pin 0)#define IR_Pin 15 // digital pin 15 (analog pin 1)#define LeftBumper 18#define RightBumper 19#define PanPin 9 #define SpeakerPin 4#define LedPin 13#define center 90// Remote control buttons#define btnPower 149#define btnMute 148#define btnPrevCh 187#define btnDown 145#define btnUp 144#define btnLeft 147#define btnRight 146#define btnPlay 1434#define btnStop 1432#define btnRecord 1437#define btnPause 1433#define btnRew 1435#define btnFwd 1436#define btnInfo 186#define btnSleep 182#define btnInput 165#define btnEnter 139#define btn0 137#define btn1 128#define btn2 129#define btn3 130#define btn4 131#define btn5 132#define btn6 133#define btn7 134#define btn8 135#define btn9 136//Variablesbyte dir=0;byte speed1=230;byte speed2=255;int turn90=400;int turn45=200;int stopTime=200;int USdistance=0;int treshold=20; //20cm min distance// remote control variables#define start_bit 2200 // Start bit threshold (Microseconds)#define bin_1 1000 // Binary 1 threshold (Microseconds)#define bin_0 400 // Binary 0 threshold (Microseconds)SoftwareServo Pan; Speaker speaker = Speaker(SpeakerPin); //-----------------------------------------------------------------------------void setup() { // set motor pins as output and LOW so the motors are breaked pinMode(Motor_1_PWM, OUTPUT); pinMode(Motor_1_Dir, OUTPUT); pinMode(Motor_2_PWM, OUTPUT); pinMode(Motor_2_Dir, OUTPUT); Stop(); pinMode(IR_Pin, INPUT); // uses an analog pin so it has to be declared as digital in pinMode(PingPin, OUTPUT); digitalWrite(PingPin, LOW); pinMode(LeftBumper, INPUT); digitalWrite(LeftBumper, HIGH); //turn on pull ups pinMode(RightBumper, INPUT); digitalWrite(RightBumper, HIGH); //turn on pull ups Pan.attach(PanPin); Pan.write(center); //90 StepDelay(); pinMode(SpeakerPin, OUTPUT); speaker.Beep(); pinMode(LedPin, OUTPUT); digitalWrite(LedPin, LOW); Serial.begin (19200); Serial.println("start"); Forward();} void loop(){ Drive(); Get_IR_Command(); //square();}void Get_IR_Command() { int key = getIRKey(); //Fetch the key Serial.print("Key "); Serial.println(key); switch (key) { case btnLeft: Left(); delay(turn45); Stop(); break; case btnRight: Right(); delay(turn45); Stop(); break; case btnUp: Forward(); break; case btnDown: Reverse(); break; case btnStop: Stop(); break; case btnMute: speaker.PlayMelody(); break; } //StepDelay(); return;}//--------------------------int getIRKey() { int data[12]; int newdata=pulseIn(IR_Pin, LOW, 100000); while(newdata>0 && newdata<start_bit) { //Wait for a start bit newdata=pulseIn(IR_Pin, LOW, 100000); } if (newdata==0) return 0; for(int i=0;i<11;i++){ data[i] = pulseIn(IR_Pin, LOW, 100000); //Start measuring bits, we only want low pulses } speaker.Beep(); for(int i=0;i<11;i++) { //Parse them if(data[i] > bin_1) { //is it a 1? data[i] = 1; } else { if(data[i] > bin_0) { //is it a 0? data[i] = 0; } else { data[i] = 2; //Flag the data as invalid; I don't know what it is! } } } for(int i=0;i<11;i++) { //Pre-check data for errors if(data[i] > 1) { return -1; //Return -1 on invalid data } } int result = 0; int seed = 1; for(int i=0;i<11;i++) { //Convert bits to integer if(data[i] == 1) { result += seed; } seed = seed * 2; } return result; //Return key number}void square(){ Forward(); delay(2000); Stop(); delay(stopTime); Right(); delay(turn90); Stop(); delay(stopTime); Forward(); delay(2000); Stop(); delay(stopTime); Right(); delay(turn90); Stop(); delay(stopTime); Forward(); delay(2000); Stop(); delay(stopTime); Right(); delay(turn90); Stop(); delay(stopTime); Forward(); delay(2000); Stop(); delay(stopTime); Right(); delay(turn90); Stop(); delay(stopTime);}void Drive(){ if (digitalRead(LeftBumper)==LOW){ digitalWrite(LedPin, HIGH); Stop(); speaker.Beep(); StepDelay(); digitalWrite(LedPin, LOW); Reverse(); StepDelay(); Stop(); StepDelay(); Right(); delay(turn45); //turn45 Stop(); StepDelay(); Forward(); } if (digitalRead(RightBumper)==LOW){ digitalWrite(LedPin, HIGH); Stop(); speaker.Beep(); StepDelay(); digitalWrite(LedPin, LOW); Reverse(); StepDelay(); Stop(); StepDelay(); Left(); delay(turn45); //turn45 Stop(); StepDelay(); Forward(); } USdistance=Read_Ping_Sensor(); Serial.print("USdistance "); Serial.println(USdistance); if (USdistance<10){ Stop(); speaker.Beep(); StepDelay(); TurnAround(); } if (USdistance<treshold){ Stop(); speaker.Beep(); StepDelay(); Avoid(); Forward(); } delay(50);}void TurnAround(){ Reverse(); Pan.write(center); StepDelay(); Stop(); Left(); delay(turn90); delay(turn90); Stop(); StepDelay(); Forward();}void Avoid(){ int prev=0; dir=2; for (byte i=0; i<5; i++){ Pan.write(i*45); StepDelay(); StepDelay(); USdistance=Read_Ping_Sensor(); if (USdistance>prev){ dir=i; prev=USdistance; } } Pan.write(center); StepDelay(); switch (dir){ case 0: Right(); delay(turn90); Stop(); speaker.Beep(); StepDelay(); break; case 1: Right(); delay(turn90); //turn45 Stop(); speaker.Beep(); StepDelay(); break; case 2: Forward(); break; case 3: Left(); delay(turn90); //turn45 Stop(); speaker.Beep(); StepDelay(); break; case 4: Left(); delay(turn90); Stop(); speaker.Beep(); StepDelay(); break; } delay(500);} // Read Sensorsint Read_Ping_Sensor(){ //digitalWrite(LedPin, HIGH); int cm=0; //trigger the sensor unsigned long value = 0; pinMode(PingPin, OUTPUT); digitalWrite(PingPin, LOW); delayMicroseconds(2); digitalWrite(PingPin, HIGH); delayMicroseconds(10); digitalWrite(PingPin, LOW); //receive the echo pinMode(PingPin, INPUT); digitalWrite(PingPin, HIGH); // turn on pull up resistor value = pulseIn(PingPin, HIGH); value=value/58; cm=int(value); //digitalWrite(LedPin, LOW); return cm;}void StepDelay() { for (byte t=0; t<10; t++){ SoftwareServo::refresh(); delay(20); }}//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++void Forward(){ digitalWrite(Motor_1_Dir, LOW); // forward digitalWrite(Motor_2_Dir, LOW); // forward analogWrite(Motor_1_PWM, speed1); // analogWrite(Motor_2_PWM, speed2); // return;}void Reverse(){ digitalWrite(Motor_1_Dir, HIGH); // reverse digitalWrite(Motor_2_Dir, HIGH); // reverse analogWrite(Motor_1_PWM, 255-speed1); // analogWrite(Motor_2_PWM, 255-speed2); // return;}void Right(){ digitalWrite(Motor_1_Dir, HIGH); // reverse digitalWrite(Motor_2_Dir, LOW); // forward analogWrite(Motor_1_PWM, 255-speed1); // analogWrite(Motor_2_PWM, speed2); // return;}void Left(){ digitalWrite(Motor_1_Dir, LOW); // forward digitalWrite(Motor_2_Dir, HIGH); // reverse analogWrite(Motor_1_PWM, speed1); // analogWrite(Motor_2_PWM, 255-speed2); // return;}void Stop(){ digitalWrite(Motor_1_PWM, LOW); digitalWrite(Motor_1_Dir, LOW); digitalWrite(Motor_2_PWM, LOW); digitalWrite(Motor_2_Dir, LOW); return;}
The effect of this technique is that the motor is alternatively driven and shorted with the ratio set by the PWM signal.
For the next version of the board, if you still want to keep the number of IO the motor bridge uses low, i'd recommend using one pin for direction and use an inverter IC to create a 'not' of the single IO line. Then you could wire one side of the bridge to the pin, the other to the 'not' of the pin. This will set the direction of the motor with one pin, and then you can PWM the enable pin. The only downside is it removes the possibility of 'braking' the motor, but the same effect can be achieved by just running a motor in reverse to some power to 'slow it down'. This is how SAGAR's first motor controller worked.
How do I let PD know that the error codes can be sent to the LED? I added the led but I didn't had it as an option for the error codes.
How can I use a IR remote control sensor? Just have a digital input (active Low) and write my own code? Arduino uses a pulsein command, does WebbotLib has it? I guess it should, as it times the pulse length for Ping sensors...
What about the Buzzer? Is it supported to make Beeps in WebbotLib?
void Speaker::Beep(){ unsigned long us; int duration_,i; int duration = 25000; int freq = 3000; us=(1000000/(freq*2)); duration_ = (duration/(us*2)); for (i=0;i<duration_;i++){ digitalWrite(_pin,HIGH); delayMicroseconds(us); digitalWrite(_pin,LOW); delayMicroseconds(us); } }
So I should not use the jumper for the LED and motors in the new version, right? The LED can flash when a servo is connected to the same pin and receives pulses, but it should not be used as statusLED at the same time. So if I can disable it then the jumper is not needed unless I want to use a wire jumper to rewire it to a different pin.
The errors puzzled me because it asked me to chose something and only uart was available. I thought that the statusLED would show up there as an option to chose from.
Note that Version 1.27 has been released along with support for the uBotino (including new motor drivers for the way you've configured the motor controller).Just try creating a new project in Project Designer. Don't add anything new - just save and then generate the project. Compile and upload. You should then find your motors turn backwards and forwards.