Tuesday, September 10, 2013

Beaglebone Black with 128x64 OLED

I compiled my I2C OLED library on my beaglebone black and with little effort, I was able to get it working. My BBB is running Ubuntu instead of Angstrom (instructions to get that flashed are in a previous post). This code was the same one running on the raspberry pi in my prior posts.

Steps taken were:
  1. Download code from github
  2. run make
  3. run the compiled executable
The I2C class was defaulted to use the address of the OLED so I didn't need to change anything. :)

Here are some images of displaying a BMP on the OLED.

Monday, September 2, 2013

Simple Xbee Tutorial

I also got a few XBee modules with USB XBee Adapters and I started to mess around with them. The reason I got the adapters is primarily two fold. First, the XBee pins are 2mm and not the standard 0.1" so they do not fit on the standard breadboard. Secondly, the USB adapter makes programming the XBee very simple. I am using X-CTU to do the programming, but you can also do it over command line using the terminal, but it's a little more complicated.

Overview
My first simple project was having  1 XBee (the coordinator in API mode) talking serial to an arduino. The second XBee (the router in AT mode) would be reading a state of a pin and reporting its value every second. It would send that information to the coordinator and the coordinator would send it to the arduino where it can be seen via the serial monitor. A contrived setup and test of the XBee, but yet it made me have to learn a few more things and research on how it works.


XBee #1 - the controller in API mode
XBee #2 - the router in AT mode














The XBee #2 (router) is hooked up to an arduino solely for power and is not using any other features on the arduino. The XBee's I/O pin has been configured (via X-CTU) to read the state of the pin every second. To change the state, I have a momentary push button and a LED wired in. Pushing the button will cause the pin to read HIGH and the LED to go on. Releasing the button will cause the pin to read LOW and the LED to go off. Here are a few more pictures to illustrate.

Understanding the data
I have the arduino (XBee #1 controller) programmed to write out the frame that the XBee #2 (router) sent to it. By analyzing the frame (of hex values) we can see the digital pin being toggled as well. The highlighted lines second to the last byte (0x10) shows that digital pin 4 read high. Why 0x10 you ask? That is because bytes 19 and 20 represent the digital pin data. byte 20 represents 8 digital pins with bit 0 corresponding to digital pin 0 and bit 7 to digital pin 7. So, 0x10 (16 decimal) is 10000 in binary which tells us that digital pin 4 is reading high.
State of digital pin changed

Sunday, September 1, 2013

TFT Display

Wow, I'm so far behind with this blog! I recently got a 2.2" 18-bit color TFT Display and hooked it up to my arduino to see what the demo looks like. Quite impressive! Especially coming from a monochrome 128x64 display! To get it working using the arduino was very straight forward and simple. I want to use this with my Raspberry Pi so the next step would be to make my own C++ driver to talk to the ILI9340 chip on the TFT. Granted, not all the functionality that the arduino library will be supported, as I just to display text and a few graphics (PNG or BMP). The TFT board also has a mini sd card slot so you could store pictures or data on there that is to be displayed. Check out the link about for all the specifications for the board.

Here are a few pictures from the arduino demo.

Sunday, August 4, 2013

Serial communication with Arduino

Been a bit busy and this is long overdue... Here is an example of serial communication between the Arduino and a computer. In this example, I'll use python to send data over the serial port. The arduino will listen and if it gets the right data, it will light up the RGB LED. Here is how things are wired.
I have the green pin connected to digital pin 7, the blue pin connected to digital pin 5, and the red pin connected to digital pin 3 on the arduino. One pin of the RGB LED is connected to ground. Please check your LED leads to see which is your ground pin. I also have 3 220 ohm current limiting resistors wired in. Nothing too special here... For the Arduino code, I have things driven from the serial communication. Based on what it receives, it will light up the appropriate LED color. For example, if "red" is received, the LED will light up red. If "blue" is received, it will light the LED in blue.



#!/usr/bin/env python

import serial
import sys

if (len(sys.argv) > 1):
    ser = serial.Serial('/dev/tty.usbmodem1421', 9600)
    bytesWritten = ser.write(sys.argv[1])
    print ("bytes written: " + str(bytesWritten))

The python script basically sends the first parameter to the serial port. In my case, the serial port i'm sending data to is /dev/tty.usbmodem1421 (this is my aruduino). The arduino acts upon 3 commands and they are "red", "green", and "blue." Anything other than those 3 commands are ignored. Here is the arduino code.
#include 

const int GREEN_PIN = 7;
const int BLUE_PIN = 5;
const int RED_PIN = 3;

int incomingByte = 0;
char buf[16];

void setup ()
{
  Serial.begin(9600);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);
  pinMode(RED_PIN, OUTPUT);

  digitalWrite(GREEN_PIN, LOW);
  digitalWrite(BLUE_PIN, LOW);
  digitalWrite(RED_PIN, LOW);
  memset(buf, '\0', sizeof(buf));
}

void loop ()
{
  if (readColorFromSerial())
  {
    if (strcmp (buf, "red") == 0)
    {
      // change led to red
      Serial.println ("changing LED to red");
      lightLED(RED_PIN);
    }
    else if (strcmp (buf, "green") == 0)
    {
      // change led to green
      Serial.println ("changing LED to green");
      lightLED(GREEN_PIN);
    }
    else if (strcmp (buf, "blue") == 0)
    {
      // change led to blue
      Serial.println ("changing LED to blue");
      lightLED(BLUE_PIN);
    }
    else
    {
      Serial.print("Invalid input '");
      Serial.print(buf);
      Serial.println("' - expected red, green, or blue");
    }
  }
}

int readColorFromSerial()
{
  if (Serial.available())
  {
    memset(buf, '\0', sizeof(buf));
    Serial.readBytesUntil('\n', buf, sizeof(buf));
    return 1;
  }
  return 0;
}

void lightLED(int pin)
{
  switch (pin)
  {
  case RED_PIN:
    digitalWrite(GREEN_PIN, LOW);
    digitalWrite(BLUE_PIN, LOW);
    digitalWrite(RED_PIN, HIGH);
    break;
  case GREEN_PIN:
    digitalWrite(BLUE_PIN, LOW);
    digitalWrite(RED_PIN, LOW);
    digitalWrite(GREEN_PIN, HIGH);
    break;
  case BLUE_PIN:
    digitalWrite(RED_PIN, LOW);
    digitalWrite(GREEN_PIN, LOW);
    digitalWrite(BLUE_PIN, HIGH);
    break;
  }
}

After compiling and uploading the sketch to the aruduino, we execute the python script.


If you open the serial monitor on the aruduino, you can see what the aruduino is doing. Here is a sample screenshot.

Here are the results you should see with respect to the LED.
Next up, using PWM to control the brightness of the LED of each color. Hopefully I can get this next blog post up within a few days...

Saturday, July 13, 2013

Raspberry Pi GPIO with RGB LED

I was playing around more with the wiringPi library and a Red Green Blue LED. I have a simple setup that will blink the led in each color. From the video, it's a bit tough to distinguish between blue and green so I included a few pictures of each color as well.

 

Tuesday, July 9, 2013

Ubuntu on BeagleBone Black

After playing around with Angstrom, I wanted to try my hand at Ubuntu so I decided to flash my BBB with the Ubuntu wheezy image. The process was relatively painless and I was about to write up what I did, but I came across a post that was very similar to my steps so I'll link that one instead.
http://avedo.net/653/flashing-ubuntu-13-04-or-debian-wheezy-to-the-beaglebone-black-emmc/

Now that I am on familiar ground, I was able to port over my code for the OLED and GPS to the BBB. Though I haven't wired it all up yet, I was able to compile it without issues. I actually waiting for another breadboard that I ordered so I won't have to tear down what I currently have just to test my BBB setup.

Monday, July 8, 2013

GPIO using the Raspberry Pi


After getting my OLED and GPS working, I wanted to mess around with the GPIO pins so I bit off something simple. Here is what my setup looks like.
  • Raspberry Pi
  • Raspberry Pi T Cobbler
  • Raspberry Pi Ribbon Cable
  • Breadboard
  • Two 1 KiloOhms resistors
  • Two 10 KiloOhms resistors - pull up resistors
  • 2 momentary pushbuttons
  • Jumper wires
In this setup, pushing the button will drive the signal low. To keep things simple and just illustrate the point, pushing the button(s) will just print out a message to stdout. In doing some research, I came across Gordon's wiringPi library. I incorporated this into my code so I didn't have to reinvent the wheel! It is pretty simple to use for my C++ application. I started out the simple way and had a loop to check the pin status and act upon it if it has changed. However, that doesn't fit my end goal so I got a bit fancier with the implementation, but the good news is that it is supported by wiringPi. The fancier implementation is to use interrupts and to have a function pointer called when the interrupt is detected. Below is the code to drive this circuit. Currently, the circuit does bounce so debouncing code will need to be added to normalize this, but hopefully this illustrates the point.
#include <iostream>
#include <wiringpi.h>

// These are wiringPi pin numbers from http://wiringpi.com/pins
#define BUTTON_1     7  // pin 7 on pi
#define BUTTON_2     3  // pin 15 on pi

using namespace std;

void interruptHandler ()
{
   cout << "in interruptHandler()" << endl;
}

void interruptHandler2 ()
{
   cout << "in interruptHandler2()" << endl;
}

int main ()
{
   if (wiringPiSetup() < 0)
   {
      cout << "uniable to initialize wiringPi library!" << endl;
      return 1;
   }

   if (wiringPiISR (BUTTON_1, INT_EDGE_FALLING, &interruptHandler) < 0)
   {
      cout << "Unable to register interrupt handler for BUTTON_1!" << endl;
      return 1 ;
   }

   if (wiringPiISR (BUTTON_2, INT_EDGE_FALLING, &interruptHandler2) < 0)
   {
      cout << "Unable to register interrupt handler for BUTTON_2!" << endl;
      return 1 ;
   }

   // wait for interrupt, but don't consume 100% of cpu
   while (1)
      delay (100);

   return 0;
}

Tuesday, July 2, 2013

Raspberry Pi GPS and LCD


Building upon the I2C and OLED from my previous posts, I connected a GPS and used the same OLED to display data. Currently, latitude, longitude, speed, and course are the values I chose to deal with first, but gpsd has much more data you can get at. I chose to do all my development with C++, but a quick google search shows many examples using Python. Once I get my C++ code working and finalized, I'll port things to Python.

The OLED is connected via I2C to the Raspberry Pi and the GPS is using the hardware UART on the Pi. The hard part is now out of the way! Next up, save the GPS data (in KML) to a file and plot that file on Google Earth.

Sunday, June 30, 2013

Hanging Lake Hike


It's been long overdue, but we finally made it to Hanging Lake Trail in Glenwood Springs, CO. Once we got there, the parking was full as it usually is on weekends! When we finally got to the trailhead, we noticed this sign. It's a bit misleading since there were many kids and many families carrying young ones so "difficult" does not really apply.

The hike is about a 1000 ft ascend and is about 1.1 miles one way. The views are very nice and the pictures below do not do it justice!

The forecast was for 92 degrees, but we lucked out as going up a passing storm went by and dropped some rain which made it much cooler.




Here are some pictures from the beginning of the trail.
For the most part, the trail consists of rock, but there are some areas where it's either gravel or dirt.

Some nice views of Glenwood Canyon are visible from the trail as well.













At the top, there is a nice view of a waterfall. Going a bit past it to Spouting Rock yields a nice waterfall and can cool you off!



Sunday, June 23, 2013

Bitmap on Adafruit 128x64 using a Raspberry Pi


It's been a while, but I *finally* got my Adafruit 128x64 OLED working to display a bitmap image. From the Adafruit forums, unfortunately (or fortunately!) they currently do not have support for C++ libraries for this display on the Raspberry Pi, which is why I had to write my own. It was also a great learning experience! The code is written in C++ so I plan to use it for my BeagleBone Black as well. I believe nothing needs to be changed, but just recompiled for that platform, but I'll test that a bit later.

The OLED memory map isn't linear; probably because it's primarily use for rendering output in text which is typically in the form of a 5x7 font. Thus, the biggest challenge is to read and rotate the data. I used an 8 byte array as the memory map is aligned that way. So reading the 8 bytes from the bitmap and rotating those bytes from being horizontal to being vertical is the biggest challenge. Essentially, that  is what I did to take advantage of how I write out the bytes. I have one method that writes out the bytes for both text and bitmap images.

Next up... Hooking up a GPS receiver and getting the output to display on the OLED. Hopefully, this should be a bit easier since I now have a library to interface with when using the OLED.

Saturday, June 15, 2013

Beaglebone Black

I kept reading good things about the Beaglebone Black and wanted to try things out for myself so I ordered one. I recently got it in the mail and it has a pretty cool look to it (though I do like the original beaglebone look better). However, this one is much more powerful and comes at a lower price. Here is a closer look.
Figure 1 - Powered on with stock image
I then wanted to upgrade to the latest image. This platform uses a different flavor of linux called Angstrom. Different commands to do similar things as I'm more familiar with RedHat (rpm based) and Ubuntu (debian based). Nothing too far fetched, so I'm sure the learning curve won't be too steep. Anyway, on to the upgrade.

As there are many blogs about how to do it, I'll just detail out what I did to get mine updated.

1. Download the latest image from here: http://beagleboard.org/latest-images

2. Uncompress the image file. I used 7zip

3. I then got my micro SD card (8GB) and plugged it into my adapter then to the computer.

4. I still had used Win32 Disk Imager since I had it installed from using different images with my Raspberry Pi. You can download it here: here

5. I then powered down the BBB and inserted the micro SD card that has the latest image that Win32 Disk Imager just wrote to it.

6. Hold down the S2 button (located on the opposite side of the RJ-45 jack. Here is an image
Figure 2 - S2 button location

7. Plug in the 5V adapter into the wall. After a few seconds the LED's begin to blink and you can let the S2 button go.

8. To flash the image, it took about 30 minutes. When it is complete, all 4 LEDs will be lit and look something like this:
Figure 3 - Flash complete

9. Disconnect power and remove the micro SD card.

10. Boot up to the new image.

Thursday, June 13, 2013

Raspberry Pi and 128x64 OLED




I recently purchased a LCD display for some projects I have going. Initially, I hooked it up to my arduino since Adafruit has libraries already written that can let you run things easily (just has to solder the header pins to the PCB and you are in business). Their library support is great and it makes things easy to use and they have some working examples too. Unfortunately (or fortunately!), if you plan to use this for a Raspberry Pi or Beaglebone Black, you are not so lucky as there are no libraries that you can download and use for those (yet!). Since I wanted to learn more about interfacing with hardware/firmware, this was a great place to start. The driver chip on the OLED board is a SSD1306 one and the datasheet is available here. I have mine connected to the PI via I2C. Note, by default, the OLED comes with SPI enabled, so closing 2 gates on the back with a little solder needs to be done to enable I2C. Just using a 2 jumper wires for clock and data, we are in business!

I was able to get some simple text up on the LCD and played around with placement (ie. centered and left justified). For me, it was easier to develop on ubuntu and copy my files over to the PI. It allowed me to do remote debugging and my core i7 was much faster than the processor on the PI. I still have a bit more functionality to add but so far it has been an enjoyable project to work on.

Friday, June 7, 2013

Reformat SD card after using it in Raspberry Pi

If you try to use your SD card after having used in your Raspberry Pi, you will notice your OS will not recognize it. OS X and Windows, it's pretty straight forward to reformat, but Linux is a bit more tricky, but here are the steps.
  1. Mount the SD card
  2. Find where the SD card is mounted. You can do this with the
    mount
    command. If you are not root, try
    sudo mount
    The SD card will be mounted to something like
    /dev/sdbx
    where x is a number.
  3. Delete the partitions from the SD card. The command to do this is
    sudo fdisk /dev/sdbx
    • p is the command to list the existing partitions
    • d is the command to delete the partition
    • delete all partitions on SD card
  4. Create a new partition
    • n is the command to create a new partition
    • p is the command to to create a primary partition
    • Enter the sector size 8192
    • press Enter to select the default last sector
    • t is the command to change the partition type
    • We want FAT32, so type b
    • w is the command to write the changes to disk
  5. Now we have our partition created, we need to format it. We can do that using this command
    mkdosfs -vF 32 /dev/sdb1
  6. That is it. You should now see this drive as a thumb drive again.

Wednesday, June 5, 2013

Linux IPC

I needed a way for my raspi program to communicate with with some events from the GPIO. Some options that quickly come to mind are sockets, shared memory, files, and signals. I wanted to briefly share an example in c++ using signals. For this example, we will use the SIGUSR1 signal, which by default, will terminate your application if not caught.

Lets create the signal handler. Pretty straight forward... If we get the SIGUSR1 signal, print out a message to stdout
// signal handler function
void sig_handler (int signo)
{
   if (signo == SIGUSR1)
      cout << "got SIGUSR1" << endl;
}

Next, we need to tell our application to listen for the signal. We do that by calling signal(). If we try to register our listener and something fails or a that signal can't be listened to, we will see an error message printed out to stdout. Note, not all message can be trapped and acted upon. For example, SIGKILL can't be caught. If you were to try and register a listener for it (I encourage you to do so), you will see it will fail.
if (signal(SIGUSR1, sig_handler) == SIG_ERR)
      cout << "Unable to catch SIGUSR1" << endl;

Now, if we put this all together and run our program, we can try to send the SIGUSR1 signal and see if we trap it in our application. Here is a complete example (signal-receiver.cpp).
#include <iostream>
#include <signal.h>
#include <stdio.h>

using namespace std;

// signal handler function
void sig_handler (int signo)
{
   if (signo == SIGUSR1)
      cout << "got SIGUSR1" << endl;
}

int main()
{
   if (signal(SIGUSR1, sig_handler) == SIG_ERR)
      cout << "Unable to catch SIGUSR1" << endl;

   // simulate a long process - calling sleep() so CPU doesn't go to 100%
   while (1)
      sleep(1);

   return 0;
}

To compile, nothing special.
g++ -Wall signal-receiver.cpp -o signal-receiver 

Run and send the SIGUSR1 signal. Notice the program does not terminate upon receiving the signal. You can send it over and over and it will not terminate. Try commenting out the adding of the listener in the program above, re-compile, and run. When you send the SIGUSR1 signal, it will terminate your application.
$ ./signal-receiver 
got SIGUSR1
got SIGUSR1
got SIGUSR1

To send the signal from the command line
$ kill -USR1 <PID>

Lastly, if you are curious if you can send a signal from another c++ program, the answer is yes! Here is a simple example.
#include <iostream>
#include <signal.h>

using namespace std;

int main (int argc, char* argv[])
{
   if (argc != 2)
   {
      cout << "Usage: " << argv[0] << " <PID>" << endl;
      return 1;
   }
   int ret;
   ret = kill(atof(argv[1]), SIGUSR1);
   if (!ret)
      cout << "Successfully sent signal";
   else
      cout << "Error sending signal";
   cout << endl;
   return 0;
}

Tuesday, June 4, 2013

Compiling for Raspberry Pi



Installed wheezy 7.0 on an 8GB micro SD card and booted my raspi. ssh'ed in and was able to test out my cross compiled program (compiled on linux). Wasn't as painful as I thought... So I took the next step and setup remote debugging as well with gdbserver. I can now compile the code on my linux machine, run it on my raspi, and also debug it from my linux machine. Pretty cool!