I started to build a two motor robot car using a NANO, BLE HM10 and L298N motor control. I got the robot to work well using the bluetooth serial app. There was a minor issue with how I was parsing the Serial communication but that is now history.
Now I want to add obstacle avoidance so I added an SG90 servo and an HC-SR04 sonar module. For now, I am switching between two modes A) control car with BLE and B) run obstacle avoidance. These are kind of working though I'm encountering an issue when I attach the servo to pin 3. Let me explain just a little more; I'm almost done....
Originally, I had the ENA on pin 10 and ENB on pin 11. The car works fine in this set up. As soon as I add "myservo.attach(3);" to my project, the servo will work, however, one of the motors stop working entirely.
So I read that Timer 1 in the NANOis feeding pins 9 and 10 and that Timer 2 feeds pins 3 and 11. Ultimately, the idea is that by attaching the servo to pin 3, it takes over the Timer so that one of the motors stops working. I updated the code so that ENA and ENB are on pins 9 and 10 respectively. The original robot car functionality works with that single change. Again, as soon as I attach the servo to pin 3 the l298n has problems. In fact, the motors stop working entirely, both of them. The servo works fine. To summarize:
scenario 1: ENA (10), ENB (11), servo (3) = one motor works, servo works
scenario 2: ENA (9), ENB (10), servo (3) = both motors don't work, servo works
I've read that I can try the SoftwareServo library and I'm looking into that now. But it would be great to understand what is happening as I think there is knowledge to be gleaned. If you have any suggestions on things to try or topics to brush up on please let me know. I think that the NANO can be used to power a robot car via BLE and also do obstacle avoidance (via servo and sonar).
Below I'm posting the code of scenario 2. A quick note on power. I thought that maybe I had too many modules connected to the NANO so I did the following:
- feeding 8V to the L298N
- enabled the 5V-EN output on the L298N so I'm getting 5V out of that one
- powering the NANO via the VIN pin that is connected to L298N 8V
- NANO 5V output powers the HM10 BLE
- L298N 5V is powering the SG90 servo and HC-SR04 sonar module
- GND from L298N is made common to NANO, BLE, SG90 and HC-SR04 modules
/*
Using ena 9 and enb 10 (which share timer 1) works. However, if I attach servo to pin 3, servo works but motors dont.
Using ena 10 and enb 11 (which use different timer) works, however, when I attach servo to pin 3, servo works and only one motor works
*/
#include <Arduino.h>
#define IN1 7
#define IN2 8
#define IN3 11
#define IN4 12
#define ENA 9 // must be pwm
#define ENB 10 // must be pwm
#define Speed 120
int ledPin = 13; // Define the LED pin
signed int direction = 0; // 2 back, 0 stop, 1 forward. Help with turning while moving
// define Servo setup
#include <Servo.h>
#define SERVO_PIN 3
Servo myservo;
const int D = 30; // delay per small increment in servo
const int I = 2; // angle increment
const int delay_per_cycle = 50; // this is the delay after the servo has swept left and right
void Backward() {
Serial.println("In Backward");
direction = -1;
analogWrite(ENA, Speed);
analogWrite(ENB, Speed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
}
void Forward() {
Serial.println("In Forward");
direction = 1;
analogWrite(ENA, Speed);
analogWrite(ENB, Speed);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
}
void Stop() {
Serial.println("In Stop");
direction = 0;
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
}
void Left() {
Serial.println("In Left");
analogWrite(ENA, Speed);
analogWrite(ENB, Speed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
delay(100);
if (direction == -1) {
Backward();
}
if (direction == 0) {
Stop();
}
if (direction == 1) {
Forward();
}
}
void Right() {
Serial.println("In Right");
analogWrite(ENA, Speed);
analogWrite(ENB, Speed);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
delay(100);
if (direction == 1) {
Forward();
}
if (direction == 0) {
Stop();
}
if (direction == -1) {
Backward();
}
}
void UltraSonic() {
Stop();
myservo.write(90); // 90 is the center line, 0 to the right, 180 to the left
delay(delay_per_cycle);
// turn to the right
for (int i = 90; i >= 0; i -= I) {
if (i % 10 == 0)
myservo.write(i);
delay(D);
}
// turn to the left
for (int i = 1; i <= 180; i += I) {
if (i % 10 == 0)
myservo.write(i);
delay(D);
}
// turn to center from the left
for (int i = 180; i >= 90; i -= I) {
if (i % 10 == 0)
myservo.write(i);
delay(D);
}
}
void setup() {
pinMode(ledPin, OUTPUT); // Set the LED pin as an OUTPUT
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
Serial.begin(9600); // Initialize Serial communication with a baud rate of 9600
Stop();
Serial.print("Attaching Servo to pin ");
Serial.println(SERVO_PIN);
myservo.attach(SERVO_PIN); // this is what makes the motors not/stop working
myservo.write(90);// move servos to center position -> 90°
}
void loop() {
if (Serial.available() > 0) { // Check if data is available to read from Bluetooth
char receivedChar = Serial.read(); // Read the incoming character from Bluetooth
if (receivedChar == 'F' || receivedChar == 'f' || receivedChar == '4') {
Forward();
}
else if (receivedChar == 'b' || receivedChar == '5') {
Backward();
}
else if (receivedChar == 'L' || receivedChar == 'l' || receivedChar == '3') {
Left();
}
else if (receivedChar == 'R' || receivedChar == 'r' || receivedChar == '0') {
Right();
}
else if (receivedChar == 'S' || receivedChar == 's' || receivedChar == '6') {
Stop();
}
else if (receivedChar == 'O' || receivedChar == 'o' || receivedChar == '1') {
UltraSonic();
}
}
}