9. Embedded programming

This week I worked on getting started with embedded programming, experimenting with an Arduino UNO and different in- and outputs.

LCD Display

Getting started and to be able to read different input devices, my first step is getting the LCD Display connected.

The display I have is “LCM-S01602DTR/M”. I found a data sheet here.

To get started, I download the Arduino IDE from the Arduino website.

In the software, we find a lot of example codes. Luckily, there is one for the display, too, called “LiquidCrystal”.

I open the example and on top I can find an explanation on how to connect the display to the Arduino:

The circuit:

  • LCD RS pin to digital pin 12

  • LCD Enable pin to digital pin 11

  • LCD D4 pin to digital pin 5

  • LCD D5 pin to digital pin 4

  • LCD D6 pin to digital pin 3

  • LCD D7 pin to digital pin 2

  • LCD R/W pin to ground

  • LCD VSS pin to ground

  • LCD VCC pin to 5V

  • 10K resistor:

  • ends to +5V and ground

  • wiper to LCD VO pin (pin 3) // here I used a potentiometer, I connected on the circuit to control the LCD contrast.

Now knowing what to connect where with help of the datasheet, I try and connect the display which works just fine!

Ultrasonic Ranging Module

In the next step, I want to write a first own program that can write the input of the ranging module to the lcd.

I found the “HC-SR04” datasheet here.

VCC and GND should be quite self-explanatory here, whereas the two remaining pins are for in- and output each.

Trigger is used to tell the sensor to send out an ultrasound.

Echo is used to measure the time it takes until the triggered sound comes back.

Here, i wrote a qucik program in Arduino IDE to measure a distance and print it on the LCD screen. It also includes a LED, that blinks quicker, the lower the distance is.

First Project

#include <LiquidCrystal.h>  //include the library for the lcd

// the lcd pins and the echo and trigger pins for sonar are declared here
// using const ints, they will never ever change during runtime!
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2, echo = 6, trigger = 7; 

// then the declared lcd pins are used to construct a LiquidCrystal object; the lcd display.
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

long duration;    // global variable to store the echo duration
float distance;     // the distance after calculation

long previousMillis = 0;     // past milliseconds since the last switching of the led took place
int interval = 1000;        // blinking interval in ms

int ledState = LOW;         // led state ...
bool ledActivated = true;   // activate the led blinking

int ledPin = 13;       // the arduinos pin the led is connected to

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);           // initialize the lcd screen and specify the dimensions

  pinMode(ledPin, OUTPUT);    // set the LEDpin
  pinMode(trigger, OUTPUT);   // define the trigger as output...
  pinMode(echo, INPUT);       // ... and the echo as input
}

void loop() {
  if (millis() % 300 == 0) {  // check if the milliseconds that have run until the program start modulo 500 equals 0 to only run the distance check every half second.
    lcd.setCursor(0, 0);                              // set the cursor to first line, first column
    lcd.print(cleanDistanceString(measure()));        // print the distance measured
  }
  blinkingInterval(distance);                         // set the blinking interval depending on the distance
  blinkLED();                                      // actually switch the led status
}

float measure(){

  // so technically, it works like that:
  // we use the TRIGGER to send a "sound", that is then measured by the ECHO by taking the time it takes to arrive back at the sensor:


  digitalWrite(trigger, LOW);     // set the voltage to 0 in order to prevent errors in the measurement to occur
  delay(5);                       // then, wait for a moment
  digitalWrite(trigger, HIGH);    // send out the ultrasonic sound
  delay(10);                      // wait for a moment again.
  digitalWrite(trigger, LOW);     // stop the sound!

  // now, using the pulseIN() function, we can measure the time it takes for the sound to arrive back at the sensor:

  duration = pulseIn(echo, HIGH); // the result is saved in the duration variable

  distance = (duration/2) * 0.03432; // now, with the power of math, we take half the duration (to only consider one way of the sound) and multiply it to have the result in cm

  // this is it for the calculation and measurement, now we return the distance value.

  return distance;
}

// The next function is used, to have clean output on the lcd, adding 0 before the number to make the "." align all time.
String cleanDistanceString(float dist){

  if (dist > 999) {           
    return "Too far away!";         // just to prevent distances above 10m
  }

  String temp = (String)dist;       // safe the distance as a string, temporarily

  if(dist < 100){
    temp = "0" + temp;              // if 2 digit number or smaller, add one "0" before the value
  }
  if (dist < 10){
    temp = "0" + temp;              // if 1 digit number, add another "0" before the value
  }

  temp += " cm";                    // and the measurement unit afterwards

  lcd.clear();                      // clear (erase all output) the lcd as close before the print to avoid screen flashing

  return temp;                      // finally, return the string
}

// the following method is used, to control an LED and make it blink 
// the tricky part is, using the delay() function would slow the whole program
// To avoid that, I use the time millis() and check how much time has past since the last time the LED was switched on or off.

void blinkLED(){   
  long currentMillis = millis();  // save the current time

  if(currentMillis - previousMillis >= interval && ledActivated){ //check if there is enough time past to do the next action and the led is allowed to blink

    previousMillis = currentMillis;           // save the current time as the last time the led was switched
    if(ledState == LOW){                      // in case it was off before. .
      ledState = HIGH;                        // .. turn it on ..
    } else {                                  // .. else ..
      ledState = LOW;                         // .. turn it off !
    } 
  }

  digitalWrite(ledPin, ledState);             // now finally write it to the LED.
}

// lastly, we will manipulate the interval variable, refering to the distance measured. the LED then can be compared to an audiosignal a parking assistant sends out in a car.

void blinkingInterval(float dist){ 

  if (distance < 100){          // if the distance is lower than 1m, it increases the blink speed depending on it
    interval = distance * 10;
    ledActivated = true;
  } else {    
    ledActivated = false;     // if the distance is higher than 1m, it is permanently deactivated
    ledState= HIGH;

  }
  if (distance < 10){
    ledActivated = false;     // if the distance is lower than 10cm, it is permanently activated
    ledState= HIGH;
  }
}

Servo Motor

One servo in the kit is the Hextronik HXT900, but its datasheet is very.. low on detail.

Another servo we have is the HKSCM9-5. Unfortunately, I can’t find a datasheet for it either. This servo is a continuous rotation servo that can’t fully rotate due to a blockade at one of the gears inside.

With the TowerPro Microservo 9G (datasheet) is very similar to the one we got in our kit this week and delivers more useful information for me to find out how to use a servo.

For the use of the servo in Arduino IDE i visited their website!

I can use the arduino library’s servo simply by sending it a value of rotation (0° - 360°) and it changes its position.

  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }

Seeing the two servos and the sound sensor, I had the idea of creating a simple little robot. Due to lack of adequate material, I had to improvise…

I disassembled one of the servos..

..and removed the parts that stop it from fully rotating..

..like that.

For the case of it, I used an old phone box I found.

I used double-sided tape to attach the servos and did some cutting (tough work with just scissors..).

From the back I can plug in the cable to test and program it.

At the front I attached the sound sensor, so the robot can measure the distance towards an obstacle in front of it.

I glued little “balls” at the end of each of the servo’s arms to make it have more friction.

Since the cable that connects a battery did not have a fitting plug for the Arduino, I used an old charging cable and cut it off.

I used two WAGO clamps to attach it.

At this point, it worked quite well already. The robot is moving very slow, though!

To make it a little faster, I designed a wheel for it, using parts from my parametric construction kit and some insulation material I found at home.

As you can see in the video above, while rotating forward the servo is lacking speed.

I’m afraid I have been a little too harsh to it and damaged it during the work..

That’s why I had to stop working on this project (which I dedicated too much time, anyways..).

Lastly, here is the code I wrote including detailed comments:

#include <Servo.h>          //include the library for a servo

// the pins used in this project are declared here
// using const ints, they will never ever change during runtime!
const int echo = 6, trigger = 7, servoMotorPin = 8, servoBrakePin = 10;

Servo servoBrake;   // Initialize the servos.
Servo servoMotor;


long duration;    // global variable to store the echo duration
float distance;     // the distance after calculation

int runSpd;       // this variable holds the "speed" of the servo, more info below

int stopBrake;      // this variable holds the angle of the servo that will work as a brake.
bool rotate = false;  // this boolean tells if the robot has to rotate or can go straight.

void setup(){         // the setup will run ONCE at the start of the arduino and is used here to attach the pins for the given cause

  pinMode(trigger, OUTPUT);     // define the trigger as output...
  pinMode(echo, INPUT);         // ... and the echo as input
  servoBrake.attach(servoBrakePin);     // attach the servoPin to the servo object
  servoMotor.attach(servoMotorPin);     // same here but for the actual motor

}

void loop(){
  if(millis() % 500 == 0){    // ever 500 ms (half a second)
    distance = measure();     // distance will be calculated here, more info below
    checkNextMove();          // the sonar sensor is used to calculate the next move (forward or backward)
    rotateServoBrake();       // and, lastly, the servos are told what to do
  }                    
}

float measure(){

  // so technically, it works like that:
  // we use the TRIGGER to send a "sound", that is then measured by the ECHO by taking the time it takes to arrive back at the sensor:

  digitalWrite(trigger, LOW);     // set the voltage to 0 in order to prevent errors in the measurement to occur
  delay(5);                       // then, wait for a moment
  digitalWrite(trigger, HIGH);    // send out the ultrasonic sound
  delay(10);                      // wait for a moment again.
  digitalWrite(trigger, LOW);     // stop the sound!

  // now, using the pulseIN() function, we can measure the time it takes for the sound to arrive back at the sensor:
  duration = pulseIn(echo, HIGH); // the result is saved in the duration variable
  distance = (duration/2) * 0.03432; // now, with the power of math, we take half the duration (to only consider one way of the sound) and multiply it to have the result in cm

  // this is it for the calculation and measurement, now we return the distance value.
  return distance;
}

void rotateServoBrake(){
  if(rotate){           // if the robot has to rotate
    stopBrake = 90;     // the braking servo will lower his arm (rotate from 0 to 90 degree rotation)
    runSpd = 180;       // and the accelerating servo will run full speed - counter-clockwise!
  } else {              // if not..
    stopBrake = 0;      // the braking servo will raise his arm (rotate back to 0 degree rotation)
    runSpd = 0;         // and the accelerating servo will run full speed - clockwise!
  }
  servoBrake.write(stopBrake);      // then, both servos are actually told what values they will have to interpret now
  servoMotor.write(runSpd);
}

void checkNextMove(){
  if(distance < 5){           // if the distance is smaller than 5cm, it will have to rotate.
    rotate = true;
  } else if(distance > 20){   // but just when the distance is greater than 20cm again, it will move forward. the threshold will prevent him from moving back and forth quickly.
    rotate = false;
  }
}