4. Electronic Prototyping#

Week’s introduction#

We started this week with an introduction of microcontrollers and an overview of their functions and how to program them. The focus expanded to practical applications, where we learned to incorporate input and output devices seamlessly into our microcontroller projects.

Programming tool#

Arduino IDE#

The Arduino IDE (Integrated Development Environment) is a software application used for programming Arduino microcontrollers. Arduino is an open-source electronics platform that provides a range of hardware and software tools to facilitate the creation of interactive electronic projects. The Arduino IDE is a key component in the Arduino ecosystem, serving as the primary interface for writing, compiling, and uploading code to Arduino boards.

Get started with the Arduino IDE#

First, you need to install Arduino IDE.
After launching the IDE, Go to your settings then “add additional board manager URLs” and then add the URL below

https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json


Now we can download the “Raspberry pi pico/RP2040” on the Board Manager


Connect your microcontroller to your pc then select “Select Board”

Choose the “usbmodem-” (the Microcontroller port)

Select the board and choose “Generic RP2040”

And you are set to begin!

Programming in C/Arduino#

In C/Arduino programming, the setup() and loop() functions are essential components of the code structure. They serve different purposes in the execution of an Arduino sketch:

setup()#

void setup() {
  // put your setup code here, to run once:

}

The setup() function is executed only once when the Arduino board starts or is reset. Its primary purpose is to initialize and set up any necessary configurations before the main program begins to run. The main tasks that are set in the setup() function are:
Initializing pins (setting them as input or output)
Configuring serial communication settings
Initializing libraries or variables
Performing any other one-time setup operations

loop()#

void loop() {
  // put your main code here, to run repeatedly:

}

The loop() function is the main part of the Arduino code. After the setup() function completes its execution, the loop() function is continuously executed in a loop for the entire duration the Arduino is powered on. Code inside the loop() function repeats indefinitely, providing the core functionality of the program. The main tasks that are set in the setup() function are:
Reading sensors
Processing data
Controlling outputs (e.g., LEDs, motors)
Managing communication

Microcontroller YD-RP2040 Pinout#

Microcontroller#

The heart of the Raspberry Pi Pico is its microcontroller. It features the RP2040 microcontroller chip, ARM cortex-M0+ 32bits, dual-core, 264k SRAM, 133MHz native (250MHz+ easy overclock), two identical PIO modules, Bootloader UF2, providing a powerful and capable computing platform for various applications.

GPIO pins#

The Raspberry Pi Pico has a set of GPIO (General Purpose Input/Output) pins that can be used for various purposes, such as reading digital or analog signals, controlling external devices, or communicating with other devices. It has 40 GPIO pins arranged in two rows (20 pins each) along the sides of the board.

Power Pins#

The Raspberry Pi Pico includes pins for power-related functions:
VUSB (Pin 40): USB power pin, used for powering the Pico when connected via USB
3V3 (Pins 36 and 38): 3.3V power pins, providing a regulated 3.3V output for external components
GND (Ground) Pins: Multiple ground pins for completing electrical circuits

USB Connector#

The Pico has a USB-C port that can be used for power supply, programming, and data transfer.

BOOT Button#

The BOOT button (in the middle next to the Small Outline 8 Mini (SO8M)) allows users to enter a mode where the Pico can be programmed or flashed with new firmware. Pressing this button while connecting the Pico to a computer via USB initiates this mode.

LED Indicator#

There is a built-in LED (LED on pin 25 at the bottom) that can be used for basic status indication or as a convenient visual output during development.

Temperature & RH sensor#

Setup#

Let’s make a Humidity and Temperature sensor using the DHT20 and our microcontroller.


First, we need to read the sensor’s datasheet to figure out how to connect it
to the microcontroller. As we can see below, the first and third pins are for power while the second and forth are for data.


Using the information from the datasheet, I connected the SDA pin to the RP2040 pin No 0, the SCL pin to the RP2040 pin No1, The VDD to the VUSB(5V) and the GND to the GND.


Program#

we will set:
The highest temperature to: 30
The lowest temperature to: 15
The highest humidity to: 75
The lowest humidity to: 15

//
// FILE: DHT20_plotter.ino
// AUTHOR: Ali Bahja
// PURPOSE: DHT20 I2C humidity & temperature sensor
//
//  Always check datasheet - front view
//
//          +--------------+
//  VDD ----| 1            |
//  SDA ----| 2    DHT20   |
//  GND ----| 3            |
//  SCL ----| 4            |
//          +--------------+


#include "DHT20.h"
#include "pico/stdlib.h"
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif




#define LED_PIN 23 // Pin number where the LED is connected
#define BRIGHTNESS 50
Adafruit_NeoPixel strip(1, LED_PIN, NEO_GRBW + NEO_KHZ800);
DHT20 DHT(&Wire);

struct Color {
  uint8_t red;
  uint8_t green;
  uint8_t blue;
};
Color led_color = {0,0,0};

void setup()
{

  Wire.setSDA(0);
  Wire.setSCL(1);
  Wire.begin();

  Serial.begin(115200);
  Serial.println("Humidity, Temperature");

  strip.begin();
  strip.show();
  strip.setBrightness(BRIGHTNESS);
  strip.setPixelColor(0, strip.Color(led_color.red,led_color.green,led_color.blue));
  strip.show();


}


void loop()
{
  if (millis() - DHT.lastRead() >= 1000)
  {

    //  note no error checking
    DHT.read();
    Serial.print(DHT.getHumidity(), 1);
    Serial.print(", ");
    Serial.println(DHT.getTemperature(), 1);
    if (DHT.getTemperature() > 30){
      Color led_color = {255,0,0};
      strip.setPixelColor(0, strip.Color(led_color.red,led_color.green,led_color.blue));
      strip.show();
      delay(50);
      if (DHT.getHumidity()<15 ){
      strip.setPixelColor(0, strip.Color(led_color.red,led_color.green,led_color.blue)); // Turn on the LED
      strip.show();
      delay(2);        // Delay for 1 second (1000 milliseconds)
      strip.setPixelColor(0, strip.Color(0,   0,   0)); // Turn off the LED
      strip.show();
      delay(2); 
      }
      if (DHT.getHumidity()>75){
        strip.setPixelColor(0, strip.Color(led_color.red,led_color.green,led_color.blue)); // Turn on the LED
        strip.show();
        delay(20);       // Delay for 1 second (1000 milliseconds)
        strip.setPixelColor(0, strip.Color(0,   0,   0)); // Turn off the LED
        strip.show();
        delay(20);
      }else{
        delay(1000);
      }
    }
    if (DHT.getTemperature() < 15){
      Color led_color = {0,0,255};
      strip.setPixelColor(0, strip.Color(led_color.red,led_color.green,led_color.blue));
      strip.show();

      if (DHT.getHumidity()<15 ){
        strip.setPixelColor(0, strip.Color(led_color.red,led_color.green,led_color.blue)); // Turn on the LED
        strip.show();
        delay(2);        // Delay for 1 second (1000 milliseconds)
        strip.setPixelColor(0, strip.Color(0,   0,   0)); // Turn off the LED
        strip.show();
        delay(2); 
      }
      if (DHT.getHumidity()>75){
        strip.setPixelColor(0, strip.Color(led_color.red,led_color.green,led_color.blue)); // Turn on the LED
        strip.show();
        delay(20);       // Delay for 1 second (1000 milliseconds)
        strip.setPixelColor(0, strip.Color(0,   0,   0)); // Turn off the LED
        strip.show();
        delay(20);
      }
      else{
        delay(1000);
      }
    }
    else{
      Color led_color = {255,255,255};
      strip.setPixelColor(0, strip.Color(led_color.red,led_color.green,led_color.blue));
      strip.show();
      delay(50);
      if (DHT.getHumidity()<15 ){
      strip.setPixelColor(0, strip.Color(led_color.red,led_color.green,led_color.blue)); // Turn on the LED
      strip.show();
      delay(2);        // Delay for 1 second (1000 milliseconds)
      strip.setPixelColor(0, strip.Color(0,   0,   0)); // Turn off the LED
      strip.show();
      delay(2); 
    }
    if (DHT.getHumidity()>75){
      strip.setPixelColor(0, strip.Color(led_color.red,led_color.green,led_color.blue)); // Turn on the LED
      strip.show();
      delay(20);       // Delay for 1 second (1000 milliseconds)
      strip.setPixelColor(0, strip.Color(0,   0,   0)); // Turn off the LED
      strip.show();
      delay(20);
    }
    }

  }
}

Demonstration#

Cold case < 15 (Humidity: 70~60, Temperature: 15.2~14.9)#

High-humidity case > 75 (Humidity: 87~76, Temperature: 20.6)#

Hot case > 30 (Humidity: 40, Temperature: 31.7)#

The SG90 Servo Motor#

This is a small simulation, using the micro servo 9g, we will control the motor and rotate it from one end to the other.


Our Servo motor has three pins/wires; this includes the VCC(Red), GND(Brown), and the Signal pin (Orange). The Signal pin is the one used to feed the control signal from the microcontroller to the servo, to get the servo to rotate to a particular angle.
After connecting the red cable to the VUSB pin, the brown one to the GND and orange to the eighth pin as seen below

We will upload this simple program to our microcontroller

// FILE: Motor Rotator
// AUTHOR: Ali Bahja

#include <Servo.h>

Servo servo;
int angle = 10;

void setup() {
  servo.attach(8);
  servo.write(angle);
  pinMode(0,INPUT_PULLUP);
}


void loop() 
{ 
 // scan from 0 to 180 degrees
  byte buttonState = digitalRead(0); 
  if (buttonState == 1){
  for(angle = 10; angle < 180; angle++)  
  {                                  
    servo.write(angle);               
    delay(15);                   
  } ;
  Serial.println(buttonState);
  // now scan back from 180 to 0 degrees
  for(angle = 180; angle > 10; angle--)    
  {                                
    servo.write(angle);           
    delay(15);       
  } ;
  Serial.println(buttonState);
  }
  else if (buttonState == 0){
    buttonState = 0;
    delay(10000);
  }
  Serial.println(buttonState);
}

And TADAAAA!!!

Air Quality Monitoring#

Using Sharp dust sensor, we can calculate dust density (mg/m^3) versus Voltage.

This sensor has 6pins(needs a 6pin mini TE connector harness):
Pin 1 (V-LED) => VUSB (connected to 150ohm resister)
Pin 2 (LED-GND) => GND pin
Pin 3 (LED) => GP2 2
Pin 4 (S-GND) => GND pin
Pin 5 (Vo) => GP0 pin
Pin 6 (Vcc) => VUSB

We will have something like this after connecting every pin with the microcontroller

Using this arduino source code, our sensor will do his job directly

/*
  Analog input, analog output, serial output

  Reads an analog input pin, maps the result to a range from 0 to 255 and uses
  the result to set the pulse width modulation (PWM) of an output pin.
  Also prints the results to the Serial Monitor.

  The circuit:
  - potentiometer connected to analog pin 0.
    Center pin of the potentiometer goes to the analog pin.
    side pins of the potentiometer go to +5V and ground
  - LED connected from digital pin 9 to ground through 220 ohm resistor

  created 29 Dec. 2008
  modified 9 Apr 2012
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/AnalogInOutSerial
*/

// These constants won't change. They're used to give names to the pins used:
const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to
const int analogOutPin = 2;  // Analog output pin that the LED is attached to

int sensorValue = 0;  // value read from the pot
int outputValue = 0;  // value output to the PWM (analog out)

void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600);
}

void loop() {
  // read the analog in value:
  sensorValue = analogRead(analogInPin);
  // map it to the range of the analog out:
  outputValue = map(sensorValue, 0, 1023, 0, 255);
  // change the analog out value:
  analogWrite(analogOutPin, outputValue);

  // print the results to the Serial Monitor:
  Serial.print("sensor = ");
  Serial.print(sensorValue);
  Serial.print("\t output = ");
  Serial.println(outputValue);

  // wait 2 milliseconds before the next loop for the analog-to-digital
  // converter to settle after the last reading:
  delay(2);
}

The graph gives us the next result