BlinkM + I2c working with little alterations


9 posts
by Grey Whittney » Fri Jul 20, 2012 11:11 pm
Not sure if this is really news for the hardware hackers, but thought to pass it along.

I've been able to get a 3 leds in one package - BlinkM (Main BlinkM Site) running from the GPIO I2C bus pins, from 3.3 v without any level changes needed.

I'm running rootfs of raspbian_wheezy with additions of the i2ctools, a cross compiled kernel from bootc's git repository, and a cross compiled blinkm code from overo-blinkm

Had to change the i2c_functions.c for the static char _i2c_bus[] to "/dev/i2c-0" from "/dev/i2c-3".

But other than that:
Code: Select all
root@raspberry-pi:~# ./blinkm find-leds

Scanning I2C bus for BlinkM devices...
Found an uknown device at address 9 (0x09) : 0x61B0
Found 1 device

root@raspberry-pi:~# ./blinkm show-scripts

Available Scripts

Id                  Name        Sequence
 0               default        white > red > green > blue > off
 1                   rgb        red > green > blue
 2           white-flash        white > off
 3             red-flash        red > off
 ...
16          thunderstorm        random blues & purples > white flashes
17            stop-light        red > green > yellow
18            morse-code        S.O.S. in white

root@raspberry-pi:~# ./blinkm play-script -s 16


notes:
rootfs: raspbian_wheezy_20120608.img
kernel: 3.2.16+ armv6l
lib: arm-linux-gnueabihf/ld-2.13.so
compiler: from crosstool-ng: arm-unknown-linux-gnueabi-gcc (crosstool-NG 1.15.3) 4.7.1 20120402 (prerelease)
--
~ Grey
Posts: 10
Joined: Fri Jul 13, 2012 6:10 pm
Location: PA, USA
by SDC » Sun Aug 05, 2012 1:52 am
Thanks for posting. I thought this was very helpful.

I wanted to be able to control BlinkM without having to re-compile code, and explored using command line control of the BlinkM through i2cset command.

Based on that, I wrote a bash script to demonstrate i2cset to play the pre-defined light shows (scripts) in the BlinkM. The code (below) doesn't require compiling any additional code. I've left in extensive comments to explain the calls and the process (e.g., installing i2ctools and adding i2c modules.

I hope this helps others explore i2c...

Code: Select all
#
# Script to write to i2c bus to play BlinkM LED pre-defined script
#
# Assumes i2c has been initialized on the Raspberry Pi
#
# Tested using Rasbian Wheezy 2012-07-15 (already includes i2c)
#
# Prerequisites:
# ==============
#
#   i2c Tools installed : 
#               sudo apt-get install i2c-tools
#
#   Modules added to '/etc/modules' file :
#               i2c-bcm2708
#               i2c-dev
#
#   Add 'pi' user to user group to read from i2c port
#               sudo usermod -a -G i2c pi
#               {logout / login}
#
#   Now should have access to i2c-0 and i2c-1
#      can check by: 
#               sudo i2cdetect -l
#
#
# Uses BlinkM device (see http://thingm.com/ OR https://www.sparkfun.com/products/8579 )
#
#       Blink M Pin     <==>     Raspberry Pi Pin
#     ----------------------------------------------
#         GND (-)                  Pin 6 - Ground
#         PWR (+)                  Pin 1 - 3.3V
#       i2c SDA (d)                Pin 3 - i2c SDA (data)
#       i2c SCL (c)                Pin 5 - i2c SCL (clock)
#
#      Blink M should be on dev i2c-0
#      can check by:
#               sudo i2cdetect 0
#
#      BlinkM device's default i2c address is 0x09
#
#     Basic command to write to i2c for Blink M is
#             i2cset -option port address data... style
#      where we'll use specific for playing script:
#           i2cset -y 0x00 0x09 0x70 0x02 0x03 0x00 i
#                   ^   ^    ^    ^    ^    ^    ^  ^
#                   |   |    |    |    |    |    |  +-- write data as i2c block
#                   |   |    |    |    |    |    +----- Start playing @ beginning
#                   |   |    |    |    |    +---------- Number of repeats (arg#2)
#                   |   |    |    |    +--------------- Script number (arg#1)
#                   |   |    |    +-------------------- Command byte for "play script"
#                   |   |    +------------------------- Address of BlinkM i2c (default)
#                   |   +------------------------------ i2c device port '0'
#                   +---------------------------------- Disable interactive mode of i2cset
#
#
#
#
#This file must have mode changed to executable to run:
#               chmod +x blinkMplay.sh
#               ./BlinkMplay.sh
#
#   2012 -- Shelton C. (SDC)

if [ $# -lt 1 ]
   then
   echo  -e "\nUsage:  $0  [-q] [-h] [script_number  [repeat_times]]"
   echo -e "         where: "
   echo -e "             -q forces BlinkM to quit the current script. "
   echo -e "             -h gives help and lists the scripts,"
   echo -e "             script_number is the ID (in HEX) of the"
   echo -e "                 pre-defined script {0x00 - 0x12}, and"
   echo -e "             [repeat_times] is the optional number of times"
   echo -e "                 to repeat the script"
   echo -e "             -q, -h, and script_number are mutually exclusive arguments.\n"
   
   exit 1
fi

if [ $# -eq 1 ] 
then
   if [ "$1" = "-q" ] ;    then
      echo "Stopping Current Script..."
      sudo i2cset -y 0 0x09 0x6f            # code to stop
      sudo i2cset -y 0 0x09 0x63 0x00 0x00 0x00 i   # code to fade to black
   
   elif [ "$1" = "-h" ] ; then
      # echo "you asked for help.  call script with no arguments and list"
      ./$0
      echo -e "\n BLINKM DEFINED SCRIPTS:"
      echo -e "Number  |    Description"
      echo -e "========|==================="
      echo -e "    0   | default startup"
      echo -e "    1   | RGB"
      echo -e "    2   | white flash"
      echo -e "    3   | red flash"
      echo -e "    4   | green flash"
      echo -e "    5   | blue flash"
      echo -e "    6   | cyan flash"
      echo -e "    7   | magenta flash"
      echo -e "    8   | yellow flash"
      echo -e "    9   | black (off)"
      echo -e "   10   | hue cycle"
      echo -e "   11   | mood light"
      echo -e "   12   | virtual candle"
      echo -e "   13   | water reflections"
      echo -e "   14   | old neon"
      echo -e "   15   | the seasons"
      echo -e "   16   | thunderstorm"
      echo -e "   17   | traffic light"
      echo -e "   18   | morse code SOS"
         
   
   elif ([ $1 -ge 0 ] && [ $1 -lt 19 ]) ; then
      echo "Playing Script $1 indefinitely..."
      sudo i2cset -y 0 0x09 0x70 $1 0x00 0x00 i
      
   else
      # one argument, but it is not understood
      echo -e "\nUnknown argument or script out of range...\n"
      exit 1                      # exit with error (not needed)
   fi
fi

if [ $# -eq 2 ]
   then
   if ([ $1 -ge 0 ] && [ $1 -lt 19 ] && [ $2 -ge 0 ]) ; then
      echo "Playing Script $1 $2 times..."
      sudo i2cset -y 0 0x09 0x70 $1 $2 0x00 i
   else
      # two arguments, but not understood
      echo -e "\n Unknown arguments or script out of range...\n"
      exit 1                     # exit with error (not needed)
   fi
fi

exit 0
--- SDC
Posts: 6
Joined: Sat Jul 28, 2012 11:09 pm
by akprincehbd » Mon Aug 06, 2012 4:43 pm
Grey Whittney wrote:Not sure if this is really news for the hardware hackers, but thought to pass it along.

I've been able to get a 3 leds in one package - BlinkM (Main BlinkM Site) running from the GPIO I2C bus pins, from 3.3 v without any level changes needed.

I'm running rootfs of raspbian_wheezy with additions of the i2ctools, a cross compiled kernel from bootc's git repository, and a cross compiled blinkm code from overo-blinkm

Had to change the i2c_functions.c for the static char _i2c_bus[] to "/dev/i2c-0" from "/dev/i2c-3".

But other than that:
Code: Select all
root@raspberry-pi:~# ./blinkm find-leds

Scanning I2C bus for BlinkM devices...
Found an uknown device at address 9 (0x09) : 0x61B0
Found 1 device

root@raspberry-pi:~# ./blinkm show-scripts

Available Scripts

Id                  Name        Sequence
 0               default        white > red > green > blue > off
 1                   rgb        red > green > blue
 2           white-flash        white > off
 3             red-flash        red > off
 ...
16          thunderstorm        random blues & purples > white flashes
17            stop-light        red > green > yellow
18            morse-code        S.O.S. in white

root@raspberry-pi:~# ./blinkm play-script -s 16


notes:
rootfs: raspbian_wheezy_20120608.img
kernel: 3.2.16+ armv6l
lib: arm-linux-gnueabihf/ld-2.13.so
compiler: from crosstool-ng: arm-unknown-linux-gnueabi-gcc (crosstool-NG 1.15.3) 4.7.1 20120402 (prerelease)



hello, now I'm working on a project which uses I2C bus. I have already install the latest firmware with Hexxeh rpi-update but I don't know how to install the kernel. I have so much difficulties on how to use the I2C on RPi now. Could you please show me how to install the kernel?

I saw the website of : http://www.bootc.net/projects/raspberry-pi-kernel/
but I cannot manage to install the " ■Pre-compiled binary for Debian: linux-image-3.2.23-rpi1+_1_armel.deb"
Posts: 3
Joined: Mon Aug 06, 2012 4:27 pm
by SDC » Mon Aug 06, 2012 5:29 pm
Perhap Grey can comment with more specifics on the original post.

From my experience...I'm using the Wheezy Raspian build (2012-07-15) and DID NOT need to install any additional kernel(s)...Just the i2c tools as noted in the comments in the script above.

Good luck with it!
--- SDC
Posts: 6
Joined: Sat Jul 28, 2012 11:09 pm
by jkuner » Mon Aug 13, 2012 5:33 pm
Hi - thanks for your posting & experimentation! I'm using a MinM and the latest wheezy raspbian. I have compiled all of the prereqs but it doesn't seem to connect. What pins are you guys actually using? I have tried connecting Pins 1 and 6 to + and - and pins 3 and 5 to the GPIO pins on MinM.

Thanks!
Posts: 1
Joined: Mon Aug 13, 2012 5:26 pm
by jwilker2 » Mon Nov 05, 2012 2:01 pm
Hello,
Thought I'd add a note saying thanks for the help, I was able to connect a BlinkM/MaxM utilizing a PI Cobbler, four jumper wires and a half size breadboard. Afterward I installed i2ctools and SDC's handy little script, and voila! Instant glowing happiness, now on to the internet controlled, I2c enabled minature Christmas Tree with countdown clock. Thanks for sharing the info.
User avatar
Posts: 44
Joined: Wed Nov 30, 2011 6:55 am
Location: Birmingham, Alabama
by greenleaf108 » Mon Nov 12, 2012 9:58 pm
SDC:

Thank you for posting your BlinkM i2c code here. I'm going to try this out when I get home later today.

Question for you; is it possible to replace any of the built-in scripts with your own? What I'm trying to do is create an ambient weather station, where the script would change based on the current weather.

Or alternatively, could your code be modified to play custom scripts?
Posts: 10
Joined: Sun Jul 22, 2012 3:53 am
by greenleaf108 » Mon Nov 12, 2012 10:04 pm
Also curious if there's an easy way to say "fade to $RGB" where RGB would be a specific color. That way the color of the BlinkM could easily be synced with the temperature, etc.
Posts: 10
Joined: Sun Jul 22, 2012 3:53 am
by pocketkk » Sat Jan 05, 2013 11:49 pm
Converted to ruby script. Does the same stuff plus you can input a hex value as well.

Code: Select all
#!/usr/bin/env ruby

# Prerequisites:
# ==============
#
#   i2c Tools installed :
#               sudo apt-get install i2c-tools
#
#   Modules added to '/etc/modules' file :
#               i2c-bcm2708
#               i2c-dev
#
#   Add 'pi' user to user group to read from i2c port
#               sudo usermod -a -G i2c pi
#               {logout / login}
#
#   Now should have access to i2c-0 and i2c-1
#      can check by:
#               sudo i2cdetect -l
#
#
# Uses BlinkM device (see http://thingm.com/ OR https://www.sparkfun.com/products/8579 )
#
#       Blink M Pin     <==>     Raspberry Pi Pin
#     ----------------------------------------------
#         GND (-)                  Pin 6 - Ground
#         PWR (+)                  Pin 1 - 3.3V
#       i2c SDA (d)                Pin 3 - i2c SDA (data)
#       i2c SCL (c)                Pin 5 - i2c SCL (clock)
#
#      Blink M should be on dev i2c-0
#      can check by:
#               sudo i2cdetect 0
#
#      BlinkM device's default i2c address is 0x09
#
#     Basic command to write to i2c for Blink M is
#             i2cset -option port address data... style
#      where we'll use specific for playing script:
#           i2cset -y 0x00 0x09 0x70 0x02 0x03 0x00 i
#                   ^   ^    ^    ^    ^    ^    ^  ^
#                   |   |    |    |    |    |    |  +-- write data as i2c block
#                   |   |    |    |    |    |    +----- Start playing @ beginning
#                   |   |    |    |    |    +---------- Number of repeats (arg#2)
#                   |   |    |    |    +--------------- Script number (arg#1)
#                   |   |    |    +-------------------- Command byte for "play script"
#                   |   |    +------------------------- Address of BlinkM i2c (default)
#                   |   +------------------------------ i2c device port '0'
#                   +---------------------------------- Disable interactive mode of i2cset

#   2012 -- Shelton C. (SDC)
#   Adapted to Ruby by Jason Crump 1/1/2013

GREEN=" 0x00 0xff 0x00 "
BLUE=" 0x00 0x00 0xff "
RED=" 0xff 0x00 0x00 "
WHITE=" 0xff 0xff 0xff "

def return_color(hex)
  hex_array=hex.scan(/../)
  color_string=""
  hex_array.each do |hex|
    puts hex
    dd=hex.to_i(16).to_s(16)
    color_string << " 0x" << dd << " "
    puts color_string
  end
  return color_string
end

class Light
  attr_accessor :repeat, :program

  def play(program, repeat)
    play_script="i2cset -y 0 0x09 0x70 " + program.to_s + " " + repeat.to_s + " 0x00 i"
    system(play_script)
  end

  def stop
    fade_to_black="i2cset -y 0 0x09 0x63 0x00 0x00 0x00 i"
    system(stop)
    system(fade_to_black)
  end

  def color(color)
    stop="i2cset -y 0 0x09 0x6f"
    system(stop)
    change_color="i2cset -y 0 0x09 0x63" + color + " i"
    system(change_color)
  end
end

light=Light.new

if ARGV[0] == "off"
    puts "Shutting down BlinkM..."
    light.stop
elsif ARGV[0].to_i.between?(1,18)
    option=ARGV[0]
    if ARGV[1] && ARGV[1].to_i.between?(1,100)
      repeat=ARGV[1]
      light.play(option,repeat)
    else
      light.play(option,0)
    end
else
  alert=""
  begin
    system("clear")
    puts "
      Number  |    Description
      ========|===================
           1   | RGB
           2   | white flash
           3   | red flash
           4   | green flash
           5   | blue flash
           6   | cyan flash
           7   | magenta flash
           8   | yellow flash
           9   | black (off)
          10   | hue cycle
          11   | mood light
          12   | virtual candle
          13   | water reflections
          14   | old neon
          15   | the seasons
          16   | thunderstorm
          17   | traffic light
          18   | morse code SOS
         red   | change to red
        blue   | change to blue
        green  | change to green
        white  | change to white
          hex  | to input hex value
          q    | quit   \n\n"
    puts alert unless alert==""
    puts "Choose one:  "
    input = STDIN.gets.strip
    if input.strip.to_i.between?(1,18)
      light.play(input,0)
      alert=""
    elsif input=="q"
      break
    elsif input=="red"
      alert=""
      light.color(RED)
    elsif input=="blue"
      alert=""
      light.color(BLUE)
    elsif input=="green"
      alert=""
      light.color(GREEN)
    elsif input=="white"
      alert=""
      light.color(WHITE)
    elsif input=="hex"
      alert=""
      puts "Enter Hex Value ( Example = 00ff00 ):"
      hex_input= STDIN.gets.strip
      light.color(return_color(hex_input))
    else
      alert="***Invalid input!***"
    end
  end while input != "q"
end
Posts: 2
Joined: Thu Oct 18, 2012 9:42 pm