Day 22: MC-1 Part III: First test

Although nothing caught fire, things did not work the way I intended them to:

  • The workaround used to activate the solenoid did not work. The front wheel barely turned.
  • The speed slider was calibrated with the wheels on the air. When the car was on the ground, it took almost full power to start moving it, although it was possible slowing it down once it was moving.
  • The live video feed (as described on Day 18) presented two to four seconds of lagging.
  • The camera shakes a lot when the car is moving.

Despite these enhancement opportunities, I consider it a success. It is my first successful circuit since I was in the 6th grade. I learnt a lot of things and had lots of fun. When I was at the University, I had a very frustrating experience trying to use the 8031 micro-controller.

For the future, I am considering the following possibilities:

  • Use relays to activate the solenoid or replace it for a servo to turn the front wheels.
  • Replace the L293D (600mA) for the L298N(2A).
  • Replace the nc program used to stream the video over the network for a home made one. Maybe replace the video for still pictures.
  • Change the camera position and/or add some shock absorber device.

Day 21: MC-1 Part II: Software

Since programming and testing on the Raspberry Pi itself is not very productive, I have created a TCP/IP library to send commands to the ServoBlaster from a Windows .NET program. I named it PiEater. My Raspberry Pi has a WiFi USB token, so I can access it without the usage of cables.

I wrote the “Truck Driver” program for the MC-1:

TruckDriver

The speed slider changes the pulse width sent to the motors through the L293D. Since it is a little harder to find the center of the slider, I added a “Stop” button that does that. The slider allows going from full power to back to full power to front.

The camera position sliders act on the servos mounted under the camera. The “Center” button centers the camera in both  horizontal and vertical axes.

Day 18: Installing the camera

I followed the instructions described in the Mod my Pi blog:

First step: Update the system:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get autoremove

Second step: Enabling the camera

sudo raspi-config

raspi-config

Third step: Installing the camera

  • Shutted down the system, removed the power cable, video cable, sd card, etc
  • Followed James Adams’ video at YouTube:

Fourth step: Taking pictures

raspistill -o raspbox.jpg

raspbox

We can also shot videos:

raspivid -o video.h264 -t 5000

These programs have several options for setting resolution, file format, etc

Day 11: LEDs and PWM using ServoBlaster

For the hardware, I used the same circuit presented on Day 10.

In order to create the PWM, I used the ServoBlaster library by Richard Ghirst. It is part of the PiBits project (look for the “Download ZIP” button in the right side of the page).

Although it is possible to use the ServoBlaster deamon from the command line, I wrote a program to gradually turn the LEDs on and off:

???????????????????????????????

C source code:

/*
blink.c
Written by Wilson Medeiros (clockeater)
Revision 1.0 - 2013-12-07

This software requires that the ServoBlaster daemon (servod) to be running:
sudo ./servod --min=0 --max=2000

ServoBlaster is a third-party library written by Richard Hirst
*/

#include <stdio.h>

void blink();
void setLeds(int green, int red);
void wait();

int main (int argc, char* argv)
{
  blink();

  return 0;
}

void blink()
{
  int cycles;

  for(cycles=0; cycles<10 ; cycles++)
  {
    int value;

    for(value = 0; value <= 2000; value += 100)
    {
      setLeds(value, 2000 - value);

      wait();
    }
    for(value = 2000; value >= 0; value -= 100)
    {
      setLeds(value, 2000 - value);

      wait();
    }
  }
}

/*
Set the pulse width for the leds
Values must be between 0 and 2000 (1 = 10 us, 2000 = 20ms)
The green led is wired to GPIO 18 and the red one to GPIO 23
Each one is wired in series with a 330 ohm resistor
*/
void setLeds(int green, int red)
{
  FILE *f;

  f = fopen("/dev/servoblaster", "a");

  fprintf(f, "2=%d\n", green);
  fprintf(f, "5=%d\n", red);

  fclose(f);
}

/*
Wait for 1/10 second
*/
void wait()
{
  usleep(100000);
}

Day 10: Connecting LEDs to the Raspberry Pi

Finally I have been able to connect some hardware to my Pi.

I used the circuit published by adafruit, wiring 330 ohm resistors to the LEDs:

???????????????????????????????

The original software was intended to change the active LED when a user received an e-mail. Since I intended to make something far simpler, I just changed the active LED every second.

Python:

In my first test, I wanted to use a tried-and-tested software in order to isolate an eventual problem. Therefore, I used the software provided by the adafruit tutorial. Since I don’t know how to program Python, I just removed the code I did not want.


#!/usr/bin/env python

import RPi.GPIO as GPIO, time

GPIO.setmode(GPIO.BCM)
 GREEN_LED = 18
 RED_LED = 23
 GPIO.setup(GREEN_LED, GPIO.OUT)
 GPIO.setup(RED_LED, GPIO.OUT)

while True:

GPIO.output(GREEN_LED, True)
 GPIO.output(RED_LED, False)

time.sleep(1)

GPIO.output(GREEN_LED, False)
 GPIO.output(RED_LED, True)

time.sleep(1)

C:

This is the language I have programmed for more years. I adapted the code from Gert van Loo & Dom in order to use only the GPIO pins connected to the LEDs.

//
// How to access GPIO registers from C-code on the Raspberry-Pi
// Example program
// 15-January-2012
// Original code from Dom and Gert (http://elinux.org/RPi_Low-level_peripherals#C)
// Revised: 15-Feb-2013
// Adapted by Wilson Medeiros (clockeater) on 30-Nov-2013
// Access from ARM Running Linux

#define BCM2708_PERI_BASE 0x20000000
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>

#define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024)

int mem_fd;
void *gpio_map;

// I/O access
volatile unsigned *gpio;
// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3))
#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))

#define GPIO_SET *(gpio+7) // sets bits which are 1 ignores bits which are 0
#define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0

#define GPIO_GREEN_LED (18)
#define GPIO_RED_LED (23)

void setup_io();

int main(int argc, char **argv)
{
 int g,rep;

// Set up gpi pointer for direct register access
 setup_io();

// Switch GPIO 18 and 23 to output mode

/************************************************************************\
 * You are about to change the GPIO settings of your computer. *
 * Mess this up and it will stop working! *
 * It might be a good idea to 'sync' before running this program *
 * so at least you still have your code changes written to the SD-card! *
 \************************************************************************/

// Set GPIO pins 18 and 23 to output

INP_GPIO(GPIO_GREEN_LED); // must use INP_GPIO before we can use OUT_GPIO
 OUT_GPIO(GPIO_GREEN_LED);

INP_GPIO(GPIO_RED_LED); // must use INP_GPIO before we can use OUT_GPIO
 OUT_GPIO(GPIO_RED_LED);

for (rep=0; rep<10; rep++)
 {
 GPIO_SET = 1 << GPIO_GREEN_LED;
 sleep(1);
 GPIO_CLR = 1 << GPIO_GREEN_LED;
 GPIO_SET = 1 << GPIO_RED_LED;
 sleep(1);
 GPIO_CLR = 1 << GPIO_RED_LED;
 }

return 0;

} // main

//
// Set up a memory regions to access GPIO
//
void setup_io()
{
 /* open /dev/mem */
 if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
 printf("can't open /dev/mem \n");
 exit(-1);
 }

/* mmap GPIO */
 gpio_map = mmap(
 NULL, //Any adddress in our space will do
 BLOCK_SIZE, //Map length
 PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory
 MAP_SHARED, //Shared with other processes
 mem_fd, //File to map
 GPIO_BASE //Offset to GPIO peripheral
 );

close(mem_fd); //No need to keep mem_fd open after mmap

if (gpio_map == MAP_FAILED) {
 printf("mmap error %d\n", (int)gpio_map);//errno also set!
 exit(-1);
 }

// Always use volatile pointer!
 gpio = (volatile unsigned *)gpio_map;
} // setup_io

Day 4: Hello world!

This was very straightforward. I didn’t have to install anything.

  • I edited the hello.c file in my preferred text editor.
  • (Optional) Print the file content in the terminal: cat hello.c
  • Compile the code: gcc hello.c -o hello
  • Execute: ./hello

HelloWorld

I have not yet researched if there is an easier way to  to this.