fbpixel
Using the Arduino Motor Shield

Using the Arduino Motor Shield

The official Arduino Motor Shield is an expansion board for the Arduino UNO and Mega microcontrollers for DC and stepper motor control. We have seen how to drive a DC motor using an H-bridge which can require a lot of wiring when using the IC simply. For an embedded application, such as a Willy robot, you will need to drive several motors in parallel. Shields are available for this purpose which will simplify the assembly.

Material

  • Computer
  • Arduino UNO
  • USB cable A Male to B Male
  • Arduino Motor Shield
  • DC motor x1 or Stepper motor x1

Principle of operation

The Motor Shield Arduino uses the L298 double H-bridge. It allows to drive motors in direction and speed with a nominal voltage between 5 and 12V and a current of 2A, up to 4A with an external voltage source.
This shield allows piloting:

  • up to two DC motors or one bipolar stepper motor
  • two analogue sensors
  • two PWM outputs as servomotors.
  • an I2C bus is available which allows the connection of compatible modules

Schematic

Compatible with UNO and Mega cards, the shield is placed directly on the Arduino card. The power supply is connected to the power terminal block. The motors are connected to the A+,A-,B+,B- terminals. The pins of the Arduino are directly connected to the pins of the integrated circuit:

  • Digital pin 12: direction DC Motor #A / Stepper #A
  • Digital pin 13: direction DC Motor #B / Stepper #B
  • Digital pin 3: vitesse DC Motor #A / Stepper #A
  • Digital pin 11: vitesse DC Motor #B / Stepper #B
  • Digital pin 9: activation brake DC Motor #A
  • Digital pin 8: activation brake DC Motor #B
  • Available inputs In2 In3 connected to analogue inputs A2 and A3
  • Available outputs Out5, Out6 connected to PWM outputs 5 and 6
    In the case of a shield, the connections are predefined. Check carefully in the technical documentation of the component how to use it.
    The motor connections are detailed in the following diagrams.

Code

To interact with the Motor Shield, we do not use a special library as it is connected to the Arduino pins directly. You can always create your own library to simplify your code.

//Parameters
const int input_voltage  = 9;//V
const int nominal_voltage  = 5;////V
const int MAX_SPEED  = int(nominal_voltage * 255 / input_voltage);
const int directionA  = 12;
const int directionB  = 13;
const int brakeA  = 9;
const int brakeB  = 8;
const int speedA  = 3;
const int speedB  = 11;
const int in2  = A2;
const int in3  = A3;

void setup() {
  //Init Serial USB
  Serial.begin(9600);
  Serial.println(F("Initialize System"));
  //Init Motor Shield
  pinMode(directionA, OUTPUT); //Initiates Motor Channel A pin
  pinMode(brakeA, OUTPUT); //Initiates Brake Channel A pin
  pinMode(directionB, OUTPUT); //Initiates Motor Channel B pin
  pinMode(brakeB, OUTPUT); //Initiates Brake Channel B pin
}

void loop() {
  readSensorMS();
  testMotorMS();
  //testStepperMS();
}

void testStepperMS() { /* function testStepperMS */
  //// Test stepper
  Serial.println("Move stepper 1 step clockwise");
  stpCW(1);
  Serial.println("Move stepper 1 step counter clockwise");
  stpCCW(1);
}

void testMotorMS() { /* function testMotorMS */
  //// Test DC motor
  Serial.println(F("-------------------------------------"));
  Serial.println(F("Avant "));
  dcForward();
  delay(500);
  Serial.println(F("Arrière "));
  dcBackward();
  delay(500);
  Serial.println(F("Arrêt "));
  dcStop();
  delay(1000);
}

void readSensorMS() { /* function readSensorMS */
  //// Read sensors
  Serial.print(F("In2 : ")); Serial.println(analogRead(in2));
  Serial.print(F("In3 : ")); Serial.println(analogRead(in3));
}

void dcForward() { /* function dcForward */
  //// set forward motion for A and B
  digitalWrite(directionA, HIGH); //Establishes forward direction of Channel A
  digitalWrite(brakeA, LOW);   //Disengage the Brake for Channel A
  analogWrite(speedA, MAX_SPEED);
  digitalWrite(directionB, HIGH); //Establishes forward direction of Channel B
  digitalWrite(brakeB, LOW);   //Disengage the Brake for Channel B
  analogWrite(speedB, MAX_SPEED);
}

void dcBackward() { /* function dcBackward */
  //// set backward motion for A and B
  digitalWrite(directionA, LOW); //Establishes forward direction of Channel A
  digitalWrite(brakeA, LOW);   //Disengage the Brake for Channel A
  analogWrite(speedA, MAX_SPEED);
  digitalWrite(directionB, LOW); //Establishes forward direction of Channel B
  digitalWrite(brakeB, LOW);   //Disengage the Brake for Channel B
  analogWrite(speedB, MAX_SPEED);
}

void dcStop() { /* function dcStop */
  //// stop motors A and B
  digitalWrite(brakeA, HIGH);   //Engage the Brake for Channel A
  analogWrite(speedA, 0);
  digitalWrite(brakeB, HIGH);   //Engage the Brake for Channel B
  analogWrite(speedB, 0);
}

void stpCW(int nbstep) { /* function stpCW */
  //// Move stepper clockwise
  for (int i = 0; i < nbstep; i++) {
    digitalWrite(brakeA, LOW);  //Disable brake A
    digitalWrite(brakeB, HIGH); //Enable brake B
    digitalWrite(directionA, HIGH);   //Set direction of CH A
    analogWrite(speedA, MAX_SPEED);   //Set speed for CH A
    delay(30);

    digitalWrite(brakeA, HIGH);  //Enable brake A
    digitalWrite(brakeB, LOW); //Disable brake B
    digitalWrite(directionB, LOW);   //Set direction of CH B
    analogWrite(speedB, MAX_SPEED);   //Set speed for CH B
    delay(30);

    digitalWrite(brakeA, LOW);  //Disable brake A
    digitalWrite(brakeB, HIGH); //Enable brake B
    digitalWrite(directionA, LOW);   //Set direction of CH A
    analogWrite(speedA, MAX_SPEED);   //Set speed for CH A
    delay(30);

    digitalWrite(brakeA, HIGH);  //Enable brake A
    digitalWrite(brakeB, LOW); //Disable brake B
    digitalWrite(directionB, HIGH);   //Set direction of CH B
    analogWrite(speedB, MAX_SPEED);   //Set speed for CH B
    delay(30);
  }
}

void stpCCW(int nbstep) { /* function stpCCW */
  //// Move stepper counter-clockwise
  for (int i = 0; i < nbstep; i++) {
    digitalWrite(brakeA, LOW);  //Disable brake A
    digitalWrite(brakeB, HIGH); //Enable brake B
    digitalWrite(directionA, HIGH);   //Set direction of CH A
    analogWrite(speedA, MAX_SPEED);   //Set speed for CH A
    delay(30);

    digitalWrite(brakeA, HIGH);  //Enable brake A
    digitalWrite(brakeB, LOW); //Disable brake B
    digitalWrite(directionB, HIGH);   //Set direction of CH B
    analogWrite(speedB, MAX_SPEED);   //Set speed for CH B
    delay(30);

    digitalWrite(brakeA, LOW);  //Disable brake A
    digitalWrite(brakeB, HIGH); //Enable brake B
    digitalWrite(directionA, LOW);   //Set direction of CH A
    analogWrite(speedA, MAX_SPEED);   //Set speed for CH A
    delay(30);

    digitalWrite(brakeA, HIGH);  //Enable brake A
    digitalWrite(brakeB, LOW); //Disable brake B
    digitalWrite(directionB, LOW);   //Set direction of CH B
    analogWrite(speedB, MAX_SPEED);   //Set speed for CH B
    delay(30);
  }
}

void dcStop() { /* function dcStop */
  //// stop motors A and B
  digitalWrite(brakeA, HIGH);   //Engage the Brake for Channel A
  analogWrite(speedA, 0);
  digitalWrite(brakeB, HIGH);   //Engage the Brake for Channel B
  analogWrite(speedB, 0);
}

Applications

  • Piloting a two-wheeled robot like Willy

Sources

Find other examples and tutorials in our Automatic code generator
Code Architect

Serial communication between Raspberry Pi and Arduino

Serial communication between Raspberry Pi and Arduino

In some projects it may be interesting to establish a serial communication between Raspberry Pi and Arduino. This makes it possible to couple the computing power and wireless interfaces of the Raspberry Pi with the inputs/outputs and the Arduino collection of modules. The first example that comes to mind is the use of this system for home automation in which the Raspberry Pi will host the control interface and intelligence and the Arduino will act as a programmable automaton acting on the components at the end of the chain (light, radiator, fan, sensors, etc.).

We will see in this tutorial how to set up a serial communication between Raspberry Pi and Arduino via the USB port. In this article we use the Arduino UNO card but it can be adapted to other types of cards with a serial connection (Nano, Mega, Feather, EPS32, ESP8266, etc.).

Prerequisite: Serial communication with Arduino,Remote access to Raspberry Pi with VNC

Hardware

  • Computer
  • Arduino UNO
  • Raspberry Pi 3B+
  • USB A Male / USB B Male

Wiring diagram

To establish serial communication between Raspberry Pi and Arduino, simply connect them with a suitable USB cable. In our case, we use a Raspberry Pi 3B+ and an Arduino UNO. So we need a USBA Male to USB B Male cable.

It is also possible to create serial communication by using the Rx/Tx pins of both components. In this tutorial we will focus on the USB connection.

  • Tx GPIO14(RPI) <-> Rx 0(Arduino)
  • Rx GPIO15(RPI) <-> Tx 1(Arduino)
  • GND (RPI) <-> GND(Arduino)

Raspberry Pi configuration

We remind you that in order to be able to use your Raspberry Pi without screen or keyboard, the VNC remote connection must be configured.

To use the serial interface of the Raspberry Pi, it must be enabled in the configuration menu. To do this, enter the following command in a terminal:

sudo raspi-config

In the menu, select “5 – Interfacing Options” then “P6 Serial” and validate.

Once the connection has been made, you can check the devices connected to the serial port by typing the command in the terminal:

lsusb

The Raspberry Pi returns the list of devices connected to the USB ports.

pi@raspberrypi:~ $ lsusb
Bus 001 Device 002: ID 2341:0043 Arduino SA Uno R3 (CDC ACM)
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

To find the name of the port to which the Arduino is connected, we use the command:

dmesg | grep "tty"

This command returns the system messages related to the serial ports. You had to find the name of the port in the last messages. In our case the port name is ttyACM0.

pi@raspberrypi:~ $ dmesg | grep "tty"
[    0.000000] Kernel command line: coherent_pool=1M 8250.nr_uarts=1 bcm2708_fb.fbwidth=1824 bcm2708_fb.fbheight=984 bcm2708_fb.fbswap=1 smsc95xx.macaddr=B8:27:EB:23:CF:07 vc_mem.mem_base=0x1ec00000 vc_mem.mem_size=0x20000000  console=ttyS0,115200 console=tty1 root=/dev/mmcblk0p7 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles
[    0.000636] console [tty1] enabled
[    0.951553] 20201000.serial: ttyAMA0 at MMIO 0x20201000 (irq = 81, base_baud = 0) is a PL011 rev2
[    0.954393] console [ttyS0] disabled
[    0.954466] 20215040.serial: ttyS0 at MMIO 0x0 (irq = 53, base_baud = 31250000) is a 16550
[    0.954570] console [ttyS0] enabled
[    5.378641] systemd[1]: Created slice system-serial\x2dgetty.slice.
[ 1455.402071] cdc_acm 1-1:1.0: ttyACM0: USB ACM device
[ 1581.980257] cdc_acm 1-1:1.0: ttyACM0: USB ACM device

Installation of the Arduino IDE on Raspberry Pi

To install the Arduino IDE on Raspberry Pi, it is best to go through the terminal. Simply enter the following lines of code:

mkdir ~/Applications
cd ~/Applications
wget https://downloads.arduino.cc/arduino-1.8.9-linuxarm.tar.xz
tar xvJf arduino-1.8.9-linuxarm.tar.xz
cd arduino-1.8.9/
 ./install.sh
rm ../arduino-1.8.9-linuxarm.tar.xz

This will then allow you to program the Arduino directly from the Raspberry Pi.

Code

Code Arduino

The library used for serial communication on the Arduino side is the same as for communicating with the serial monitor, the Serial.h library that we know well. Make sure that the communication speed is the same for both devices (baudrate=9600) otherwise the communication will not work.

String nom = "Arduino";
String msg;

void setup() {
  Serial.begin(9600);
}

void loop() {
  readSerialPort();

  if (msg != "") {
    sendData();
  }
  delay(500);
}

void readSerialPort() {
  msg = "";
  if (Serial.available()) {
    delay(10);
    while (Serial.available() > 0) {
      msg += (char)Serial.read();
    }
    Serial.flush();
  }
}

void sendData() {
  //write data
  Serial.print(nom);
  Serial.print(" received : ");
  Serial.print(msg);
}


Code Python

In this tutorial we will use the Python language on the Raspberry Pi side. The library used to manage the serial communication is the serial library.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# lsusb to check device name
#dmesg | grep "tty" to find port name

import serial,time


if __name__ == '__main__':
	
	print('Running. Press CTRL-C to exit.')
	with serial.Serial("/dev/ttyACM0", 9600, timeout=1) as arduino:
		time.sleep(0.1) #wait for serial to open
		if arduino.isOpen():
			print("{} connected!".format(arduino.port))
			try:
				while True:
					cmd=input("Enter command : ")
					arduino.write(cmd.encode())
					#time.sleep(0.1) #wait for arduino to answer
					while arduino.inWaiting()==0: pass
					if  arduino.inWaiting()>0: 
						answer=arduino.readline()
						print(answer)
						arduino.flushInput() #remove data after reading
			except KeyboardInterrupt:
				print("KeyboardInterrupt has been caught.")

Result

The Raspberry Pi sends the order “Hello Arduino” to the Arduino, and the Arduino replies with its name and the order received.

Practical example

Once communication is established between Raspberry Pi and Arduino, the interesting thing is to control the Arduino’s I/O and retrieve the sensor values. In this example, we will define different commands:

  • one to retrieve sensor values
  • one for switching the LED on and off on pin 13

Code Arduino

The Arduino returns data when it receives the “data” command and switches the LED connected to pin 13 on and off according to the “led0” and “led1” commands.

const int ledPin=13;
String nom = "Arduino";
String msg;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin,OUTPUT);
}

void loop() {
  readSerialPort();

  if (msg == "data") {
    sendData();
  }else if(msg=="led0"){
    digitalWrite(ledPin,LOW);
    Serial.println(" Arduino set led to LOW");
  }else if(msg=="led1"){
    digitalWrite(ledPin,HIGH);
    Serial.println(" Arduino set led to HIGH");
  }
  delay(500);
}

void readSerialPort() {
  msg = "";
  if (Serial.available()) {
    delay(10);
    while (Serial.available() > 0) {
      msg += (char)Serial.read();
    }
    Serial.flush();
  }
}

void sendData() {
  //write data ledState x sensor1 x sensor2
  Serial.print(digitalRead(ledPin));
  Serial.print("x");
  Serial.print(analogRead(A0));
  Serial.print("x");
  Serial.print(analogRead(A1));
}


Code Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# lsusb to check device name
#dmesg | grep "tty" to find port name

import serial,time


if __name__ == '__main__':
	print('Running. Press CTRL-C to exit.')
	with serial.Serial("/dev/ttyACM0", 9600, timeout=1) as arduino:
		time.sleep(0.1) #wait for serial to open
		if arduino.isOpen():
			print("{} connected!".format(arduino.port))
			try:
				while True:
					cmd=input("Enter command (data,led0 or led1): ")
					arduino.write(cmd.encode())
					#time.sleep(0.1) #wait for arduino to answer
					
					while arduino.inWaiting()==0: pass
					if  arduino.inWaiting()>0: 
						answer=str(arduino.readline())
						print("---> {}".format(answer))
						if cmd=="data":
							dataList=answer.split("x")
							print("led state : {}".format(dataList[0]))
							print("Analog input A0 : {}".format(dataList[1]))
							print("Analog input A1: {}".format(dataList[2]))
							
							arduino.flushInput() #remove data after reading
							
			except KeyboardInterrupt:
				print("KeyboardInterrupt has been caught.")

Once the two codes have been uploaded and launched, it can be seen that when the “data” command is entered into the terminal, Arduino returns many bytes containing the sensor values. It is possible to separate this response into a list using the split() function and the “x” character and, in this way, recover the sensor values and the status of the led. With this code we can control the status of the LED on pin 13.

By modifying this code, you will be able to control and observe any entry/exit of the Arduino on the Raspberry Pi.

Application

  • Create a graphical user interface (GUI) under Raspberry Pi to drive an Arduino and retrieve sensor values

Sources

Find other examples and tutorials in our Automatic code generator
Code Architect

Using a PCA9685 module with Arduino

Using a PCA9685 module with Arduino

The PCA9685 module is a 16-channel controller that can control 16 PWM outputs via I2C communication. It allows, among other things, to free inputs and outputs of your microcontroller and to drive up to 16 LEDs or servomotors (or any other module taking a PWM signal as input) using two pins (SCL and SDA) while keeping the pins of your microcontroller for other modules such as sensors.

Prerequisite: Driving a servomotor with Arduino

Hardware

  • Computer
  • ArduinoUNO
  • USB A Male to B Male cable
  • PCA9685Module

Principle of operation

The module is based on the PCA9685 controller, which allows PWM outputs to be controlled using I2C communication and an integrated clock. This module has 6 bridges to select the board address and to place on the same bus up to 62 controllers for a total of 992 actuators (available addresses 0x40 to 0x7F).
It can drive PWM outputs with adjustable frequency and 12-bit resolution. The module is compatible with 5V and 3.3V microcontrollers.

Diagram

The module is equipped with an I2C bus and a power input. The I2C bus is connected as follows:

  • Pin A5 or SCL to the SCL pin of the module
  • Pin A4 or SDA to the SDA pin of the module
  • Pin 5V to the Vcc pin of the module
  • Pin GND to the GND pin of the module In this tutorial we use the Arduino UNO board but it can be adapted to other microcontrollers. To do so, just adapt the I2C pins available on the microcontroller in question and possibly the code.

Code

To use the PCA9685 module, we use the library Adafruit_PWMServoDriver.h. PWM widths are usually given in microseconds over a period of 20ms (50Hz) but these values can change from one actuator to another and between vendors. You will have to modify the values in the code to adapt them to your actuator.
In our case, we use the MG90S actuator whose ranges are 400-2400µs over 20ms.

To set the PWM command, the library provides two functions: setPWM() and writeMicroseconds(). The writeMicroseconds() function allows us to use the constructor values directly. For the setPWM function, we need to find the corresponding pulse width on 4096 (2^12, 12bits).

Example: The frequency is 50Hz so a period of 20ms or 20000µs.

  • pwmvalmin=400/20000×4096=81.92-> 90 rounding off with a safety margin
  • pwmvalmax=2400/20000×4096=491.52 -> 480 rounding off with a safety margin

Which gives us the following equivalence:

  • pca.writeMicroseconds(i,400) equals pca.setPwm(i,0,90)
  • and pca.writeMicroseconds(i,2400) equals pca.setPwm(i,0,480)

It’s up to you to use the function that suits you best.

//Libraries
#include <Wire.h>//https://www.arduino.cc/en/reference/wire
#include <Adafruit_PWMServoDriver.h>//https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library

//Constants
#define nbPCAServo 16

//Parameters
int MIN_IMP [nbPCAServo] ={500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500};
int MAX_IMP [nbPCAServo] ={2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500};
int MIN_ANG [nbPCAServo] ={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int MAX_ANG [nbPCAServo] ={180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180};

//Objects
Adafruit_PWMServoDriver pca= Adafruit_PWMServoDriver(0x40);

void setup(){
//Init Serial USB
Serial.begin(9600);
Serial.println(F("Initialize System"));
pca.begin();
pca.setPWMFreq(60);  // Analog servos run at ~60 Hz updates
}

void loop(){
  pcaScenario();
}

void pcaScenario(){/* function pcaScenario */ 
////Scenario to test servomotors controlled by PCA9685 I2C Module
for (int i=0; i<nbPCAServo; i++) {
  Serial.print("Servo");
  Serial.println(i);
      //int middleVal=((MAX_IMP[i]+MIN_IMP[i])/2)/20000*4096; // conversion µs to pwmval
      //pca.setPWM(i,0,middleVal);
      for(int pos=(MAX_IMP[i]+MIN_IMP[i])/2;pos<MAX_IMP[i];pos+=10){
        pca.writeMicroseconds(i,pos);delay(10);
      }
      for(int pos=MAX_IMP[i];pos>MIN_IMP[i];pos-=10){
        pca.writeMicroseconds(i,pos);delay(10);
      }
      for(int pos=MIN_IMP[i];pos<(MAX_IMP[i]+MIN_IMP[i])/2;pos+=10){
        pca.writeMicroseconds(i,pos);delay(10);
      }
      pca.setPin(i,0,true); // deactivate pin i
    }
}

int jointToImp(double x,int i){/* function jointToImp */ 
////Convert joint angle into pwm command value
     
      int imp=(x - MIN_ANG[i]) * (MAX_IMP[i]-MIN_IMP[i]) / (MAX_ANG[i]-MIN_ANG[i]) + MIN_IMP[i];
      imp=max(imp,MIN_IMP[i]);
      imp=min(imp,MAX_IMP[i]);
      
 return imp;
}

Math behind jointToImp

The function joinToImp() does the same as the map() function in Arduino. It converts a value from a range to another following a linear equation.

  imp=map(x,MIN_ANG,MAX_ANG,MIN_IMP,MAX_IMP);

We know that the relation between the angle and the impulsion width is linear, thus, we can describe this equation by

imp = a * x + b

The idea is to find the coefficients a and b. For this we need two equations. what we know is that :

  • when x=MIN_ANG then y=MIN_IMP
  • when x=MAX_ANG then y=MAX_IMP

Which leads to the following equations:

MIN_IMP = a * MIN_ANG + b

MAX_IMP = a * MAX_ANG + b

Working around those two equations, we can solve a and b in two steps:

  • Substract equations

MAX_IMP - MIN_IMP = a * (MAX_ANG - MIN_ANG)

a = (MAX_IMP - MIN_IMP)/(MAX_ANG - MIN_ANG)

  • Replace a in equation

MIN_IMP = (MAX_IMP - MIN_IMP)/(MAX_ANG - MIN_ANG) * MIN_ANG + b

b = MIN_IMP - (MAX_IMP - MIN_IMP)/(MAX_ANG - MIN_ANG) * MIN_ANG

We can then deduce the conversion equation

y = (MAX_IMP - MIN_IMP)/(MAX_ANG - MIN_ANG) * x + MIN_IMP - (MAX_IMP - MIN_IMP)/(MAX_ANG - MIN_ANG) * MIN_ANG

y = (x - MIN_ANG) * (MAX_IMP - MIN_IMP)/(MAX_ANG - MIN_ANG) + MIN_IMP

Applications

  • Control the Quadrina6 robot

Sources

Find other examples and tutorials in our Automatic code generator
Code Architect

Summary on the if statement in C

Summary on the if statement in C

The if statement is the basic conditional structure and is found in all programming languages. It allows you to execute different blocks of code according to a condition. It is the basis of many algorithms and allows a computer to make a choice based on the data sent to it.

Syntax of the if statement

The if statement takes, as input, a condition in the form of a boolean variable and executes a block of instructions if it is true (in this case we say that the condition is fulfilled) and another if it is false.

  if(condition){
    <liste d'instructions si condition=true>;
  }else{
    <liste d'instructions si condition=false>;
  }

Example of a code determining the sign of a variable with the if statement:

int val=-10;

void setup() {
  Serial.begin(9600);
}

void loop() {
  if(val>=0){
    Serial.println(F("Value is positive"));
  }else{
    Serial.println(F("Value is negative"));
  }
  val=val+2; //increment val
  if(val>10) val=-10; // set val to initial value
  delay(500); //delay for monitor display
}

A boolean is a type of variable equal to true( 1-true) or false(0-false). In the C(Arduino) language, boolean variables are initialized using the keyword bool or boolean. A boolean can be obtained in different ways

  • The result of a logic test <,>,==,!=,!
 condition = variable == 10;    // variable égale à 10? 
 condition = temperature>30;   // temperature est supérieure à 30 
 condition = vitesse <= 100    // vitesse inférieure ou égale à 100 
 condition = !true // condition égale  non vraie (faux) 
   
  • The result of a function
bool test(int val){
  //retourne vraie si la valeur est supérieur à 200
  return val>200;
}
  • The result of several conditions
condition=(temperature>30) && (vitesse<20);

Other syntaxes

The if statement can have several syntaxes depending on the case.

It is possible to forget the braces when the only instruction is on one line.

  if(condition) <instructions>;

Example:

if(condtion) Serial.println("Conditon est réalisée");

If there is no instruction to execute when the condition is not fulfilled, it is possible to forget the else{} block.

  if(condition){
    <liste d'instructions>;
  }

If several conditions are evaluated at the same time

  if(condition){
   // <liste d'instructions si condition==true>;
  }else if(condition2){
    //<liste d'instructions si condition==false && condition2==true>;
  }else if(condition3){
    //<liste d'instructions si condition==false && condition2==false && condition3==true>;
  }else{
    //<liste d'instructions si aucune condition réalisée>;
  }

Things to remember

  • the if statement takes as input a condition represented by a boolean variable
  • The condition can be a function that returns a boolean or the result of a test with the logical operators =, !=, <, >, !
  • the condition is between brackets
  • the instruction block is between braces {}
  • If the instruction list is on a single line then there is no need for braces

Bonus

In simple cases, it is possible to use the “?” statement with the following syntax

resultat = (condition) ? <instruction si vraie> : <instruction si faux>

Example, line of code that returns the sign of a variable:

 
  int signe= (variable>=0) ? 1:-1; // retourne 1 si la valeur est positive et - 1 si elle est négative

Make sure you understand booleans and logical operators to use the if statement correctly. Once you have mastered this statement, your algorithms will be able to make good decisions.

Sources

Connect your Arduino to internet with Ethernet Shield  VMA04

Connect your Arduino to internet with Ethernet Shield VMA04

Connecting Arduino to internet is made possible with the use of an Ethernet Shield VM04. The basis for creating connected object (IoT) is to connect them to a network such as the WiFi network.
Communication via the Ethernet network is very convenient when you want to connect a device to WiFi.

Prerequisites: Knowledge of HTML/CSS

Hardware

  • Computer
  • ArduinoUNO
  • USB A Male/B Male
  • Ethernet cable RJ45
  • Ethernet Shield VMA04

Operating principle

The communication uses the Ethernet network which can be linked to the WiFi. To access the Arduino board without having to connect to the Internet router, it is necessary to create a bridge between wifi and ethernet connection to your computer. For this, we must:

  • Go to the Network and Sharing Center
  • Go to “Change adapter settings”
  • Select Ethernet and Wifi/(internet source) and right click
  • Click “Create Bridge”

In Windows, the control terminal, type “arp -a” to see the IP addresses used on the network.

The Ethernet Shield VMA04 uses Microchip ENC28J60 as Ethernet controller.
Note: Write a web page can take a lot of memory space for an Arduino board. We use an Ethernet VMA04 Shield and Arduino UNO board but if you think that your page will be memory-intensive upgrade to a shield W5100.
(Warning: Shield VMA04 exists version KA04 Kit soldering oneself Check the one you want to buy.)

Schematics

The Ethernet Shield VMA04 is compatible with the Arduino UNO and Mega microcontrollers and is placed directly on the map. In the case of a shield, the connections are predefined. Make sure the component’s technical documentation how to use it (VMA04 datasheet).
The ethernet shield VMA04 uses:

  • 10 and 2 pins on a map Arduino UNO
  • the SPI bus: 11,12,13 pins on an Arduino UNO

Code

To interact with the Ethernet Shield VMA04 we use the library UIPEthernet.h

  • Ethernet.begin () to initialize a network connection
  • server.begin () to initialize a server
  • EthernetClient client=server.available() to initialize a client
  • client.read () to read data from the client
  • client.print () to send data to the client
//Libraries
#include <UIPEthernet.h>//https://github.com/UIPEthernet/UIPEthernet

//Parameters
String request ;
unsigned long refreshCounter  = 0;
IPAddress ip(192, 168, 1, 179) ;
byte mac [6] = {0x54, 0x34, 0x41, 0x30, 0x30, 0x31};

//Objects
EthernetServer server(80);
EthernetClient client;

void setup() {
  //Init Serial USB
  Serial.begin(9600);
  Serial.println(F("Initialize System"));
  //Init VMA04
  Ethernet.begin(mac, ip);
  while (!Ethernet.begin(mac)) {
    Serial.println(F("failed. Retrying in 1 seconds."));
    delay(1000);
    Serial.print(F("Starting VMA04..."));
  }
  pinMode(4, OUTPUT);
  server.begin();
  Serial.println(F("VMA04 initialized"));
  Serial.print(F("IP Address: "));
  Serial.println(Ethernet.localIP());
}

void loop() {
  client = server.available();
  clientRequest();
  handleRequest();
}

void clientRequest( ) { /* function clientRequest */
  ////Get client request
  if (!client) {
    return;
  }
  //Wait until the client sends some data
  while (!client.available()) {
    delay(1);
  }

  request = client.readStringUntil('\r');//Read the first line of the request
  Serial.println(request);
  client.flush();
}

void handleRequest( ) { /* function handleRequest */
  ////Handle web client request
  if (request.indexOf("/dig4on") > 0) {
    digitalWrite(4, HIGH);
  }
  if (request.indexOf("/dig4off") > 0) {
    digitalWrite(4, LOW);
  }
  if (request.indexOf("GET") >= 0) {
    webpage(client);
    client.stop();
  }

}

void webpage(EthernetClient client) { /* function webpage */
  ////Send webpage to client

  //output HTML data header
  client.println(F("HTTP/1.1 200 OK"));
  client.println(F("Content-Type: text/html"));
  client.println();
  //header
  client.print(F("<!DOCTYPE HTML><html><head><title>AranaCorp</title>"));
  client.print(F("<meta http-equiv='content-type' content='text/html; charset=UTF-8'>"));
  //meta-refresh page every x seconds
  client.print(F("<meta http-equiv='refresh' content='2'>"));
  client.print(F("</head><body bgcolor='black'><br>"));
  client.print(F("<hr/><hr>"));
  client.print(F("<h1 style='color : #3AAA35;'><center> AranaCorp - Arduino Web Controller </center></h1>"));
  client.print(F("<hr/><hr>"));
  client.println("<center><p style='color:white;'>");
  client.print(F("Page refresh number: "));
  client.print(refreshCounter);//current refresh count
  client.println("</p></center><br>");
  client.print(F("<h2 style='color:green;'>Arduino Inputs</h2>"));
  client.println("<p style='color:white;'>");

  client.print(F("<br><br>"));
  client.print("<br><br>");

  //output analog input pin
  for (int i = 0; i < 6; i++) {
    client.print("<b>Input A");
    client.print(i);
    client.print(" : </b>");
    client.print(analogRead(14 + i));//A0=14, A1=15 ,etc.
    client.print(F("<br>"));
  }
  client.print(F("</p><br>"));

  client.print(F("<h2 style='color:green;'>Arduino Outputs</h2>"));
  client.print(F("<p style='color:white;'>"));

  //digital output
  client.print(F("<br><br>"));

  client.print(F("<b>Digital output Pin 4 : </b>"));
  client.print("<input value=" + String(digitalRead(4)) + " readonly></input>");
  client.print(F("<a href='/dig4on'><button>Turn On </button></a>"));
  client.print(F("<a href='/dig4off'><button>Turn Off </button></a><br/>"));

  client.print(F("</p><br>"));

  //file end
  client.print(F("<br></body></html>"));
  refreshCounter += 1;
  delay(1);
}

Result

We can see that the Ethernet Shield VMA04 initializes correctly. When you enter the IP address in the browser address bar, the web page described in the webpage function should appear.
Once the page loads, the analog input values ​​vary with each refresh and the status of the pin 4 can be changed by pressing the corresponding buttons.

Applications

  • Use a web interface to control your Arduino

Sources