Category: Arduino

Arduino compatible designs and projects.

  • Using the Timer1 and Timer3 libraries with the Arduino Leonardo.

    (NOTE: PJRC HAS SINCE UPDATED THE LIBRARY TO INCLUDE THE LEONARDO)

    I have been teaching Physical Computing for Artists with the Arduino Uno for over a year now and this year I decided to move to the Leonardo with the hope that a USB-Midi based core will be finished sometime soon. Its cheaper than the uno and it has a serial port that isn’t busy and best of all it doesn’t reboot every time you talk to it.

    I usually introduce background tasks using the Timer1 library since it makes timers manageable for the novice. However the existing Timer1 and Timer3 libraries are not currently avaliable for the leonardo (or any of the 4 32u4 based processors). Fortunately there is a “port” of the library for the Teensy2.0 at http://www.pjrc.com/teensy/arduino_libraries/TimerOne.zip, for some reason the leonardo is missing from the boards supported but no matter the fix is pretty easy and now I can get back to teaching.

    
    diff ~/Downloads/TimerOne/config/known_16bit_timers.h TimerOne/config/known_16bit_timers.h 
    11,22c11,34
    < 
    < // Teensy 2.0
    < //< 
    < // Teensy 2.0
    < //
    < #elif defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY)
    <   #define TIMER1_A_PIN   14
    <   #define TIMER1_B_PIN   15
    <   #define TIMER1_C_PIN   4
    <   #define TIMER1_ICP_PIN 22
    <   #define TIMER1_CLK_PIN 11
    <   #define TIMER3_A_PIN   9
    <   #define TIMER3_ICP_PIN 10
    < 
    ---
    > // mega34u4
    > // Ehem: it would be nice to figure out the sparkfun micro-pro
    > // and the adafruit u4 stuff as well.
    > #elif defined(__AVR_ATmega32U4__) 
    >     // Teensy 2.0
    >     #if defined(CORE_TEENSY)
    >         #define TIMER1_A_PIN   14
    >         #define TIMER1_B_PIN   15
    >         #define TIMER1_C_PIN   4
    >         #define TIMER1_ICP_PIN 22
    >         #define TIMER1_CLK_PIN 11
    >         #define TIMER3_A_PIN   9
    >         #define TIMER3_ICP_PIN 10
    >     // otherwise assume Leonardo/micro/esplora
    >     #else 
    >         #define TIMER1_A_PIN   9
    >         #define TIMER1_B_PIN   10
    >         #define TIMER1_C_PIN   11
    >         #define TIMER1_ICP_PIN 4
    >         #define TIMER1_CLK_PIN 12
    >         #define TIMER3_A_PIN   5
    >         #define TIMER3_ICP_PIN 13
    >     #endif
    > 

    http://www.suspectdevices.com/reference/Timer1.tgz

  • Two New Continuing Education Courses for the Rainy Season.

    Arduino for Artists.

    (The class formerly known as Physical Computing for Artists)

    During the summer break Donald Delmar Davis went to ITP Summer Camp 30 days of more intersection between art and technology than anyone can take in. He is hoping that he can use what he learned to teach more artists about how to integrate the arduino into their tool set. This year he will be working with the Arduino Leonardo with the intention of bringing midi and other usb clsses into the Arduino’s capabilities.

    https://cereg.pnca.edu/p/adult/s/407

    Tube Amplifiers.

    During the summer Mark Keppinger piloted a new class that he is offering this fall. In the class you get to build and take home a tube amplifier (for your guitar, iPhone/iPod, etc). This includes both the electronics and the cabinet to hold it.

    https://cereg.pnca.edu/p/adult/s/405

  • BikeWedge: adding an external clock to opensprints/goldsprints_fx.

    Watch while I pull another race clock system out of my hat.

    A couple of years ago Rapha gave me the mechanical race clock that I helped build for them 5 years ago and its been laying around in my pile since then. Three weeks ago Chrome bags called me up and asked if they could take it with them on a 4 month promotional tour. There wasn’t time to build out new hardware but I told them if they bought the open sprints sensor hardware we could work something out.

    The first week was spent paring the device down from 4 bikes to two bikes. Two of the driver boards had issues and the shaft on the smallest dial was bent so it is a good thing they only wanted 2. The bushings on the last two dials needed to be cleaned up since they were binding. This is not my strength but I was able to figure it out.

    While I was waiting for the sensors I built a test rig like the one that I just threw away from a pair of cds mounted on motors driven by a trusty L293D This time I put it in a box so that it might survive between use.

    Once we got the open sprints gear we got down to the fun part.

    I had done a sensors only setup for Chrome several years ago. Getting the setup to work using serial and ruby on the Macintosh was really painful and I can see pretty clearly why they have since dropped the support for the old software and gone with a flash based software  written by a third party called Goldsprints_FX. Since flash doesn’t talk to serial devices the sensors on the arduino based open sprints are proxied to a network connection using serproxy or “tinkerproxy”. I could not find the source code for tinker proxy so I went with the serproxy.

    Proxying the Proxy.

    What I needed to do was to intercept the sensor values from the opensprints arduino based hardware and the go and reset values from the goldsprints software. I started looking at the source code for the serproxy and making a network tap, then I experimented with socat. Both of which seemed too complicated. Finally I went back to the python in a nutshell book and mangled the socket in and out samples into a very simple proxy. The proxy passes data from 5330 (which is where serproxy is sending the serial data) to and from 5331 which is where goldsprints_fx expects the serproxy to be.

    import socket
    import re
    isocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    osocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    isocket.connect(('localhost',5330))
    isocket.settimeout(0.2)
    print "Connected to serproxy"
    osocket.bind(('',5331))
    osocket.listen(1)
    
    try:
        while True:
            connection,address=osocket.accept()
            if not connection: break
            print "Connected From", address
            connection.settimeout(0.2)
            while True:
                try:
                    receivedData = connection.recv(8192)
                except socket.error:
                    receivedData=None
                if receivedData is not None:
                    # print ">"+re.escape(str(receivedData))+">"+str(len(receivedData))
                    isocket.sendall(receivedData)
                    for chunk in receivedData.split('\x00'):
                        if len(chunk)>0 and chunk[0] == 's':
                            print "(RE)SET RACE !!!"
                        if len(chunk)>0 and chunk[0] == 'g':
                            print "GO !!!"
                    if len(receivedData)==0:
                        print "ISSUE WITH CLIENT"
    
                try:
                    sentData = isocket.recv(8192)
                except socket.error:
                    sentData=None
                if sentData is not None:
                    #print "<"+re.escape(str(sentData))+"<"+str(len(sentData))
                    connection.sendall(sentData)
                    for chunk in sentData.split('\x00'):
                        #if len(chunk.rstrip('\r')):
                        #    print "<",re.escape(chunk),len(chunk)
                        if len(chunk) > 4 and chunk[0]=='0' :
                            done1=int((float(chunk[3:])/1566.0) * 100.00)
                            print "Bike # 1 is ", str(done1), "percent done"
                        if len(chunk) > 4 and chunk[0]=='1' :
                            done1=int((float(chunk[3:])/1566.0) * 100.00)
                            print "Bike # 2 is ", str(done1), "percent done"
                    if len(sentData)==0:
                        print "ISSUE WITH SERPROXY"
    
    finally:
        connection.close()
        osocket.close()
        isocket.close()

    The print statements which are commented out above allowed me to see both sides of the conversation while picking out the pieces that I needed. This works pretty well at getting the data.

    $./serproxy.py
    Connected to serproxy
    Connected From ('127.0.0.1', 61571)
    (RE)SET RACE !!!
    (RE)SET RACE !!!
    GO!!!!!!!!!!
    Bike # 1 is  0 percent done
    Bike # 2 is  0 percent done
    ...
    Bike # 1 is  100 percent done
    Bike # 2 is  100 percent done
    (RE)SET RACE !!!
    $

    To make this drive the clock required retooling the clock code a bit and configuring serproxy. Since the opensprints uses the old ftdi based arduino the name of the device on the Macintosh is unique to the does not change. I bought a pair of sparkfun “red boards” and also added proxies for the clock and the test rig. Now the code to talk to the clock is the same as talking to the other network sockets. On top of that I can telnet to the test rig and set the “bike” speeds.

    Once this was working I also modified the opensprints basic_msg code to provide more frequent updates since the clock is rather jerky when it gets new positions every 250ms. Cutting it to 50ms eliminates most of that, as you can see from the video below.

    The current version of the code starts serproxy and Goldsprints_fx and kills them when done it is posted at https://github.com/suspect-devices/bikewedge/blob/master/RetoolingForOpenSprints/bin/bikewedge.py. The entire project including the 3 arduino sketches, serproxy source code and configuration file and the bikewedge proxy can be found at https://github.com/suspect-devices/bikewedge

  • Arduino Cult Induction, 10 Nov 2012, FreeGeek, $35

    Time to go kick some leaves around….

    Remember: This quarter is the most important quarter of your entire life.

    More information at http://www.suspectdevices.com/blahg/workshops/

  • Using the Arduino core as a library

    Dumbest thing ever.

    For the last year I have been working with a piece of software that was started two years ago by another programmer in Arduino using the Arduino mega2560. It has since grown into several thousand lines of code across a small pile of libraries maintained in a git repository. There are units of this which have been installed in offices around the country and to update the code we send around a pair of linux laptops with a script that backs up the dataloggers and the old firmware and uploads the current firmware.

    To get the firmware out of the Arduino IDE my clients hardware engineer is required to download the new source code from the git repository, bring up the Arduino IDE build in verbose mode and then manually copy the hex file from its obscure location to the git repository commit and push the resulting code. Then he has pull the code to the repositories on the update machines. Testing code is roughly the same process except for finding the hex file.

    It is pretty much the dumbest thing ever.

    The Arduino Preprocessor

    The history of the Arduino preprocessor is almost a decade long. The preprocessor’s job is pretty simple — hide as much confusing detail as possible from the novice user do a bunch of the users detail work and compile all of the dependencies. When Wiring was created this was done by pile of Java using regular expressions. 10 years later, it remains one. Here is its source code: https://github.com/arduino/Arduino/blob/master/app/src/processing/app/preproc/PdePreprocessor.java

    If you are used to doing these things yourself and controlling the organization of your code then the Arduino preprocessor does some really arbitrary and annoying things. Try sharing a common file between your sketch and modules (libraries) which you may or not use depending on what sketch you are compiling. It will compile everything in the directory with the included file. You have no say in what gets compiled and in what context.

    What’s that in the shadows?

    Ok, so it simplifies the users experience. But does it really make things clearer? Lets look at a trivial example designed for the target (novice) audience.

    /*
    Blink -- This example code is in the public domain.
    */
    void setup() {
    pinMode(13, OUTPUT);
    }
    
    void loop() {
    digitalWrite(13, HIGH); // set the LED on
    delay(1000); // wait for a second
    digitalWrite(13, LOW); // set the LED off
    delay(1000); // wait for a second
    }
    

    If you hold the shift key down while compiling your code you will find that along with the arduino core there is a Blink.cpp file that is created by the preprocessor. Its buried in a temporary location in this case

    /var/folders/pT/pTwTtnMcHL0MMWMWt3BuNU+++TQ/-Tmp-/build1406962201643661317.tmp/Blink.cpp

    Must be pretty scary stuff. Lets take a look at what its done.

    /*
    Blink -- This example code is in the public domain.
    */
    #include "Arduino.h"
    void setup();
    void loop();
    
    void setup() {
    pinMode(13, OUTPUT);
    }
    
    void loop() {
    digitalWrite(13, HIGH); // set the LED on
    delay(1000); // wait for a second
    digitalWrite(13, LOW); // set the LED off
    delay(1000); // wait for a second
    }
    

    The preprocessor added 3 lines of code. These lines are needed to tell the compiler to use the definitions needed to make things like pinMode, digitalWrite and Delay “just work”. It also tells the compiler about the functions the user defined. You still don’t get to see the main loop which calls setup and loop. Loop is a misnomer since if you could see it you would find a function that is called repeatedly, losing its context every time. So the novice is still relatively sheltered from the details in order to make things easy for them. They aren’t however sheltered from fact that they are actually just programming in the gnu/g++ language. This could have been accomplished in other ways, for instance it would not be extremely difficult for the editor to add those lines, if the user forgot them.

    “Make”ing it a little better.

    If you google for Arduino make file you should find at least two or three branches off of the makefile that  Nicholas Zambetti, David A. Mellis & Hernando Barragan wrote that used to be included in the Arduino. I took the one that fit the most closely to my target application and trimmed it down. https://github.com/mjoldfield/Arduino-Makefile I also added some (still a bit buggy) support for Windows. Then I put the makefiles include (Arduino.mk) in the same directory as the core for the stable branch of the arduino (I am conservative and found serious flaws in arduino 1.0’s serial handling so it is 0022 in this case).

    I compile my code one last time in the IDE and put the resulting cpp file in a directory called csource/<Sketchname>/

    Then I put my Makefile in the same directory.

    MCU = mega2560
    ARDUINO_LIBS =
    USER_LIBS = Monitor Wire DS2482
    include ../../arduino/Arduino.mk

    Since I use xcode as my primary development IDE I set up my build settings to make install from that directory and I am done. It would not be incredibly difficult to add this to the Arduino IDE “clunky” though it is. More importantly updating the code from the repository becomes a matter of two command lines.

    git pull
    make install

    Which is much less painful for me and my client. In fact the update machines can do it themselves.

    You can find the result (minus my clients project code) at https://github.com/suspect-devices/arduino-core-0022

    Warning: Experimental

    This is a solution that I needed. It is not complete and it should be regarded as highly suspect. Also while I have been able to use it it build on windows finding the serial port without an external program is problematic at best. Nevermind the lack of a real shell outside of cygwin or powershell. You have been warned.

  • Resources for the Newly Inducted

    Now that you’ve taken the plunge into microcontrollers, here are some good resources to help you with your first project.

    Books
    • Getting Started in Electronics by Forrest Mims
      A good resource if you have zero experience with electronics.
    • Physical Computing: Sensing and Controlling the Physical World with Computers by Dan O’Sullivan and Tom Igoe
      Covers all the common use cases for kinetic sculpture and other art applications. The example code is being updated for Arduino-compatible microcontroller boards by Don as Errata for Physical Computing.
    • Practical Electronics for Inventors by Paul Scherz
      If you have some basic understanding of electronic principles, this is the book for you.

    I would also recommend Forrest Mims’ Engineers Mini Notebooks, as they have lots of common circuits that you can use for a variety of projects.

    Sites

    If you have other sites or books or other resources that have been helpful, post them to the comments and (eventually) I’ll add them to this list.

  • Arduino Cult Induction, FreeGeek 19May12 1-5pm, $35

    Space is limited to 15 people so please RSVP sooner rather than later.

    http://suspectdevices.com/workshops.html

  • Two small sketches that will not work on your Arduino Mega2560.

    A few months ago Paul Stoffregon asked to borrow an arduino mega 2560 to look at a bug that he was working around. I had access to several as I was working on a project for a client that was based on the same board. Around the same time I made the mistake of trying to add a watch dog timer to a complicated piece of code that I inherited. The results were disastrous and made me look more closely at both the stripped down opti-boot boot-loader that the arduino team is using and the not so stripped down but still buggy stk500v2 code that is currently on the arduino mega2560 which is there because opti-boot doesn’t handle the larger memory.

    I was not so happy.

    I am less happy with the fact that two years after issues #181 and a year and a half after #393 were filed you can still buy an arduino mega2560 with these bugs and re-burning the boot-loader will not fix the problem.

    Issue #393.

    void setup() {
     Serial.begin(9600);
    }
    
    void loop() {
     Serial.println("test!!!");
    }

    The above sketch will not load through the bootloader.

    #include <avr/wdt.h>
    
    print "Hello world\n";
    wdt_enable(WDTO_15MS);
    
    print "I am going to not get stuck..\n";
    for(x=0; x<100; x++) {
      wdt_reset();
      x++;
      delay(10);
    }
    print "I am going to get stuck now..\n";
    for(x=0; 1; x++) {
      delay(10);
    }

    The above sketch will hang the board until you power down or re-burn the boot-loader, setting the WDT to 15ms and waiting is a common practice for getting a clean software reset. But more importantly the WDT is an vital tool to make sure that systems don’t get stuck for long periods when things go wrong (and they do).

    Fortunately some people aren’t waiting and there is source code for the bootloader that has these issues resolved is here.

    https://github.com/msproul/Arduino-stk500v2-bootloader

    and a hex file for the bootloader is at the bottom of the issue #181 if this direct link doesn’t work.