Marc's Public Blog - Arduino Hacking


All | Aquariums | Arduino | Btrfs | Cars | Cats | Clubbing | Dining | Diving | Electronics | Exercising | Flying | Hiking | Japan2017 | Linux | Linuxha | Public | Rc | Sciencemuseums | Snow | Solar | Trips



Table of Content for arduino:

More pages: April 2017 January 2017 February 2016 January 2015 September 2013 January 2012 December 2011 May 2011 January 2011




2017/04/24 Adafruit GFX on NeoMatrix and RGB Matrix Panel Demo
π 2017-04-24 00:00 in Arduino
Give me code:
  • https://github.com/marcmerlin/Adafruit_NeoMatrix/tree/master/examples/MatrixGFXDemo
  • https://github.com/marcmerlin/RGB-matrix-Panel/tree/master/examples/PanelGFXDemo
  • All the displays, 4 made with neopixels and soldered by hand
    All the displays, 4 made with neopixels and soldered by hand

    Yeah, the 24x24 one took forever to lay out, glue and solder (6H+)
    Yeah, the 24x24 one took forever to lay out, glue and solder (6H+)

    More than 2 years ago, I spent many hours writing an interrupt written driver for LED matrices that require fast line scanning while you setup the right rows, and even faster per color refreshes where you turn the color on and off depending on how bright you want each color component to be to yield different color mixes. This is explained in more details on my page on Driver for direct driving single to 3 color LED Matrices with software PWM.

    Then came in Neopixels which can be individually addressed without fast row scanning, and the Adadfruit Neomatrix library. Those made creating color matrices much more trivial (except for the part where you have to actually build and solder that matrix):

    2 row scanned matrices on the upper left, 7x7 neomatrix, another row scanned 32x16 Adafruit panel.
    2 row scanned matrices on the upper left, 7x7 neomatrix, another row scanned 32x16 Adafruit panel.

    on the bottom row, self built 16x8 neomatrix, and another 12x12 neomatrix
    on the bottom row, self built 16x8 neomatrix, and another 12x12 neomatrix

    I ended up taking my old Adafruit GFX demo I wrote fro my interrupt driven scan matrices, porting it to Neomatrix (which was trivial) and then extending it. You can find my MatrixGFXDemo code here,
    Soon afer, I dug up my Adafruit 16X32 RGB LED Matrix Panel, setup an old Arduino Mega to control it and have enough RAM left to run some fun code (on an Uno memory would have been too tight), it turns out that thanks to Adafruit GFX support, it took very little time to get my same demo working on the RGB Panel.

    Here is a video of the demo I wrote on all those different displays:

    Here are some things the demo does:

  • Init displays the same 8x8 pattern as many times as it will fit

  • The code will then draw lines, rectangles and circles that match the size of the display:


  • If the display is at least 16x8, it will display the resolution in various ways appropriate to the display size:




  • another part of the demo displays an 8x8 color pixmap with drawRGBBitmap I added in Adafruit-GFX-Library and bounces it around on any display bigger than 10x10:


  • then, it will display a 24x24 bitmap which on most displays will be panned around to show the whole picture:


  • Hope you enjoy the demo, it should work pretty trivially on any display that supports Adafruit::GFX, see https://github.com/marcmerlin/RGB-matrix-Panel/blob/master/examples/PanelGFXDemo/PanelGFXDemo.ino#L21 on how some backend specific code can be #define'd to work on other backends.

    2017/04/16 IoTuz Driver ported to Expressif ESP32 WROVER board
    π 2017-04-16 00:00 in Arduino
    As explained on this page, I wrote a pretty extensive driver-set for an ESP32 based board with lots of IO, but hardly anyone has that board (fewer than 100 made), so I ported what I could of the code to the WROVER.


    Sadly the WROVER lacks a touch screen, so you'll have to wire at least a rotary encoder or a joystick. In the demo above I also wired 2 neopixels and an IR receiver to mirror the hardware on the IoTuz.

    Source code: https://github.com/marcmerlin/IoTuz

    See this video for a demo:

    You'll definitely want to read https://github.com/marcmerlin/IoTuz/blob/master/README.md carefully, especially the WROVER section.

    On an ILI3941 based WROVER, you should also be able to play tetris and breakout:

    Enjoy!

    2017/04/03 Arduino 328P Uno Teensy3.1 ESP8266 ESP32 IR and Neopixels
    π 2017-04-03 00:00 in Arduino, Clubbing, Electronics
  • Why my pants needed IR controlled neopixels :)
  • Why IR and Neopixels at the same time, is hard
  • Concurrent IR + Neopixels solution #1: be fast (Teensy 3.1)
  • Concurrent IR + Neopixels solution #2: don't use the CPU for neopixels (ESP8266 (I2S) and ESP32 (RMT))
  • Software and Libraries
  • Video with the whole story and details
  • Show me the code!

    Sure, it's here: https://github.com/marcmerlin/Neopixel-IR (but go to the end of this page for more details).

    Why my pants needed IR controlled neopixels :)

    I mean, don't everyone's pants need neopixels? :)

    I started with a silver shirt, I added a few LEDs, and then more I got from a swap meet, and later added some LED shows I hacked to last 12H instead of 4



    Here is a 6mn clip showing the shoes and shirt if you'd like the details:

    The problem with my shirt, though, is that the colors you see on the picture are actually due to broken traces, causing the colors you see. It's better than nothing, but not what I was trying to do, and no way to create streaming effects. This is of course where neopixels come in.

    I'm not going to repeat the excellent Adafruit Neopixel Uberguide here, but I have a 3mn video clip showing a standard IR RGB LED controller, compared to a neopixel strip. It also shows how I use standard remote control servo cables to wire neopixels, and how to watch out for:

  • signal wire being in the center, so you must not feed 5V on the middle wire like you would with RC and servos
  • how if you have a neopixel strip that doesn't work right, you can only connect to the first LED, and you have to start cutting off LEDs from the strip one by one until you get to the first one that works
  • before you start cutting, make very sure you aren't connecting to the last LED (DO vs DI)
  • Why IR and Neopixels at the same time, is hard

    So, the main point of this page is however to look into the issues of controlling Neopixels and receiving IR signals at the same time.

    It's easy to listen for IR, and then change neopixels, leave them alone, and listen for IR again. It's hard (or near impossible on some chips) to actively update neopixel strips for animations and listen for IR commands at the same time.

    Why? This video explains the issue:

    What's going on is on low end arduino chips (328p, leonardo, or even AT mega and all other 16 bit AVRs), neopixels are controlled by stopping chip interrupts and sending a very precisely timed signal to the neopixels. If the timing is off just a little bit, the wrong colors get sent, or nothing works at all. This is why interrupts must be disabled


    Now, there are actually many other addressable multicolor LED types. The nice ones are 4 wire and work via SPI, which allows the CPU to control the timing and the clock, removing this exact bit banging timing issue. The cheaper 3 wire ones have a set clock and require that the CPU sends a very precisely timed signal, usually done while disabling interrupts. See https://github.com/FastLED/FastLED/wiki/Overview

    But since neopixel strips (aka WS2811/WS2812/WS2812B) is what I already had, I now had to deal with this precise timing issue. As you can guess, disabling interrupts causes issues with the IRRemote library because it has its on interrupt handler timer that also requires being run at a special timing, or it doesn't capture proper IR signals.
    The end result is that you cannot disable interrupts and receive IR signals, and if you don't disable interrupts, the neopixel signal is unstable and the colors flicker (demonstrated int the video above).

    So, unless you use some special hardware to drive neopixels strips on an AVR chip, concurrent IR + neopixels is just not going to work.

    an arduino nano v3 running neopixel strips
    an arduino nano v3 running neopixel strips

    my 328p arduiny chip (equivalent to arduino nano) and anti plug backwards toothpicks :)
    my 328p arduiny chip (equivalent to arduino nano) and anti plug backwards toothpicks :)

    because my 328p chip was unprogrammed, I had to figure out direct ISP programming pinout for it and I flashed a bootloader on it
    because my 328p chip was unprogrammed, I had to figure out direct ISP programming pinout for it and I flashed a bootloader on it

    Concurrent IR + Neopixels solution #1: be fast (Teensy 3.1)

    a few chips for comparison (uno, leostick, nano v3, arduiny, and Teensy 3.1 in green)
    a few chips for comparison (uno, leostick, nano v3, arduiny, and Teensy 3.1 in green)

    Thanks to better FastLED hardware support, when I moved my code to a Teensy 3.1 32 bit ARM CPU, the CPU was fast enough that it had time to re-enable interrupts in the middle of updating neopixels. This in turns allowed the IR Remote interrupt handler to just barely run in between pixel updates, and capture IR codes. Success!

    See this video for details:

    The magic code that makes this work, is here: https://github.com/FastLED/FastLED/blob/master/platforms/arm/k20/clockless_arm_k20.h#L34
    sei(); delayMicroseconds(WAIT_TIME); cli();

    Thanks to this re-enabling of interrupts, things work.

    So at this point, someone sensible would have declared victory. However, I felt bad wasting a Teensy 3.1 on something as simple as driving a single neopixel strip (it can drive 8 in parallel) and reading from an IR receiver, when it has around 32 I/O ports. This is why I checked if I could get this to work on ESP8266 chips which are even cheaper and have much fewer I/O pins (but add Wifi)

    Concurrent IR + Neopixels solution #2: don't use the CPU for neopixels (ESP8266 (I2S) and ESP32 (RMT))

    I had more 32bit chips, so I thought I would give them a try. I tried the ESP8266 and ESP32:


    First, the ESP8266 mostly worked with FastLED + IRRemote, but not quite. The FastLed code, just like on Teensy, is nice enough to re-enable interrupts for a short while: https://github.com/FastLED/FastLED/blob/master/platforms/esp/8266/clockless_esp8266.h#L45

    os_intr_unlock();
    delayMicroseconds(WAIT_TIME);
    os_intr_lock();

    However in my tests, the IRremoteESP8266 library was maybe a little bit too slow and caused occasional visible neopixel glitching. This is where I found this interesting library: https://github.com/JoDaNl/esp8266_ws2812_i2s/ which manages to drive the neopixels without doing bit banging with interrupts disabled ((ab)-using the I2S hardware support). It's not a very fancy library in what it offers, but it works perfectly with interrupts enabled.

    Same thing for ESP32. Actually ESP32 is even more difficult to get a perfect timing out of using bit-banging given that it's a dual core CPU running on top of an RTOS, and no matter how precise your code is, you just cannot guarantee that it'll run perfectly at the timing you need all the time. I did add ESP32 support to the Adafruit Neopixel library, but it only works most of the time, which isn't really good enough.
    This where its built in RMT support comes in. It can generate 8 precise signal waves, which are perfect for neopixels, so this is the way to go to animate neopixels without disabling interrupts (making IR receiving trivial). IRremote was missing ESP32 receive support, but I added it recently, so it's all working.

    Here's a video summary of ESP8266 and ESP32:

    Software and Libraries

    So, here's a summary of all the libraries I went through, 2 for IR, and 4 for Neopixels:
  • To receive IR signals, we'll use the excellent IRremote lib: https://github.com/z3t0/Arduino-IRremote
  • ESP8266 currently uses a fork of IRRemote, IRremoteESP8266 which may soon be in the process of being merged in the main Arduino-IRremote. See https://github.com/markszabo/IRremoteESP8266/issues/148 and https://github.com/z3t0/Arduino-IRremote/issues/400#issuecomment-294446261 .
  • For neopixels, most people use the adafruit lib: https://github.com/adafruit/Adafruit_NeoPixel . It works ok, but it requires disabling interrupts (and is therefore incompatible with IRRemote for concurrent operation)
  • FastLED is a more complete library with better hardware support (both in pixels and CPUs): https://github.com/FastLED/FastLED . The big plus of this lib is that it support re-enabling interrupts on 32bit chips, allowing the IRremote ISR to run.
  • Instead of FastLED (which does work), on ESP8266 you can use https://github.com/JoDaNl/esp8266_ws2812_i2s/ . The support is bare, but uses an inventive (ab)use of the I2S subsystem (I2C for audio) to generate neopixel signals using an onboard co-processor unit without tying up the main CPU or requiring the disabling of interrupts.
  • On ESP32, FastLED isn't supported yet (I added support in Adafruit-Neopixel) but both require disabling interrupts at least temporarily and it's hard to do anything real time on a dual core ESP32 running on top of an RTOS. The good news however is that it has 8 RMT channels which are designed to handle precise signals like this without tying up the CPU. See this code that supports Neopixels with exact timing: https://github.com/MartyMacGyver/ESP32-Digital-RGB-LED-Drivers
  • And here is my code again: https://github.com/marcmerlin/Neopixel-IR

    The big plus from that example code is that it supports 4 different Neopixel backends and abstracts them so that the adafruit (and other) demos can run on all 4 libs. See how it does it here: https://github.com/marcmerlin/Neopixel-IR/blob/v1.0/Neopixel-IR.ino#L275

    Video with the whole story and details

    This is a 25mn mashup of all the video clips, including a section on flashing the arduiny via ISP (AVR 328p):
    2017/01/16 IoTuz Driver for our ESP32 board built at Open Hardware Miniconf at Linux.Conf.au 2017
    π 2017-01-16 00:00 in Arduino, Linux
    I went to meet the Open Hardware Miniconf team to hang out the previous day and see them at work finishing the last boards:


    last minute hardware patching
    last minute hardware patching


    The IoTuz board was a challenge compared to previous years. It was based on the still new ESP32 and had very little example code. Most of the hardware had never been exercised since the board had been designed, and with a few other people I took the task to heart. Within the week, I was able to get the SPI touch screen working at the same time than the LCD (which required cable select switching via I/O expander lines. It took longer to get the two APA106 (neopixel-like) LEDs to work:

    I had the first etch-a-sketch working :)
    I had the first etch-a-sketch working :)

    So, that all in January. But IoTuz was the gift that kept on giving. It had all those I/O bits that didn't work at all and no one had ever used. Hell, some of them had no existing drivers at all (Neopixel no support under arduino IDE, IO expander needed some access functions, No support for the IR receiver, touch screen needed a few hacks, joystick needed some code to support the huge dead zone in the center), while some other hardware worked out of the box with existing drivers (temp/humidity and accelerometer). The rotary encoder also needed custom ESP32 interrupt code to work properly (nothing too fancy, but there was no existing driver to use).

    So, I embarqued into a mega library/object to support most of the hardware and ended up with almost 1000 lines of code for my IoTuz library, and another thousand lines or so for the main example code (examples/fulldemo) and that does not include 3rd party code of existing demos I was able to re-use and port to IoTuz.

    In the end, that took about 100 hours of work since I had to write/port drivers as I went along, and learn how some of that hardware was even supposed to work :) (ok, non trivial time was also spent finding and chasing platform bugs which have now been fixed, as well as merging driver code with upstream maintainers).

    Here is a quick video summary (longer videos at the bottom):

    And here is the result (thanks to https://github.com/marcmerlin/IoTuz 's examples/fulldemo)

    I made an adjustable touch menu system
    I made an adjustable touch menu system


    drawing circles with the accelerometer by rotating the board
    drawing circles with the accelerometer by rotating the board

    touch color selector
    touch color selector

    hardware scroll of bitmap using the rotary encoder
    hardware scroll of bitmap using the rotary encoder



    Just like the joystick not being very precise or centered right, the touchscreen isn't quite the same for everyone, but especially in my case I broke my touchscreen, had to buy another one and that one was wired reversed, so I designed a screen touch screen calibrator which auto adjusts and supports touch screens that are inversed like mine:


    Enough bla-blah, show me the code: https://github.com/marcmerlin/IoTuz

    And here are some video clips:

    Hardware Intro

    IoTuz Controls

    IoTuz Infrared Support

    IoTuz Demos

    IoTuz Breakout and Tetris

    Again, here's the code: https://github.com/marcmerlin/IoTuz

    2016/02/01 ESPlant, Arduino Miniconf at Linux.Conf.AU 2016
    π 2016-02-01 00:00 in Arduino, Linux
    Another year, another arduino miniconf, this year, the LCA open hardware folks brought us the ESPlant, a new board meant to monitor plants, and based off the ESP8266, the super cheap wifi chip that can now be used with the arduino IDE and libraries thanks to a compat layer.

    Jon, opening the miniconf
    Jon, opening the miniconf

    The Melbourne Hardware Hacking team who worked on this
    The Melbourne Hardware Hacking team who worked on this





    Jon gave a cool talk on the hardware assembly machine he built to put those boards together, impressive:



    Short of having a plant nearby, I concentrated on making pretty lights on the LED strip :)


    blinkie achieved :)
    blinkie achieved :)

    I added my blinky code here: https://github.com/marcmerlin/ESPlant

    Demo:

    2015/01/06 Driver for direct driving single to 3 color LED Matrices with software PWM
    π 2015-01-06 00:00 in Arduino
    Code download: Multi Color PWM LED Matrix Driver.

    Many LED matrices come with a MAX7219 driver chip or equivalent. Those are great since you program the columns and rows, and they do the line by line scan and refresh for you. Unfortunately, you can't do color mixes with different intensities for each color. For instance the Adafruit LED backpack is super easy to use, but you cannot control each color to mix different shades between them.

    Then, I also happened to have some raw LED matrices a dual color one and a triple color one ordered from china, equivalent to these two: https://www.sparkfun.com/products/682 and https://www.sparkfun.com/products/683 . Those didn't come with any driver chip, so that gave me an excuse to program my own code to do line scanning and refresh like many examples you find on the net.

    My bycolor matrix has common cathode, green and red on the 2 anodes. Like other matrices you have to disable all the lines, set the rows you'd like for each color, and then turn on the common ground to illuminate those pixels for a little while. Then, you go to the next line, and continue. Many examples do this in the main arduino loop, but I wanted to use Adafruit's excellent Adafruit-GFX library. As a result, I wrote an ISR (interrupt routine) to rrefresh the lines, like an old cathodic raw tube, in the background, while leaving the main loop for programming what you want to do and display. This soon allowed me to display the smiley face bitmap from the Adafruit LED Backpack library.

    from here
    from here

    to here
    to here

    This was pretty major accomplishment for me since I wrote a generic C++ library that could allocate an array of any size (it supports anything, not just 8x8), and do all the work in the background in an ISR. I then got busy with other projects and hobbies.

    Later, I came back to this and added code to support more than one color, and especially support programming an LED array of 1 to 3 separate colors wired either directly or via shift registers, or a combination of the 2 (shift registers save pins, but also make IO 50% slower). By then I was hitting issues where I had to refresh the lines very quickly (200 microseconds) to allow for 16 shades per color and still offer a 40-50Hz refresh rate for the whole array. If my refresh became slower than 200 microseconds, I could not support 16 shades (4 bits per color) without getting too slow and creating an array that would visibly flicker. I fixed this by doing the following:

  • Fast Digital IO to make digitalwrite 3x faster and my ISR routine 2.5x faster
  • Instead of having 16 interruptions for 16 levels per color, I switched to binary code modulation where I could do the same 16 levels of shading with only 4 interrupts instead of 16. This also leaves more time for code in the main loop.
  • I've published my resulting code here: Multi Color PWM LED Matrix Driver. While it uses more resources than the adafruit backpacks, it's cheaper in hardware and ends up giving more flexibility (many more colors).

    Before you ask me for help, READ THIS PLEASE :)

  • If you don't know the basics of LED matrices and shift registers, go read the links at the bottom of this page which show wiring for direct wiring and shift registers.
  • Or if you want shift registers in a nutshell, go here: https://www.youtube.com/watch?v=bqfPZXEuyuc
  • Shift registers + LED matrix, see: https://www.youtube.com/watch?v=2m3PbCvcqkY
  • For a wiring diagram see: http://learnpic32.blogspot.co.nz/2014/06/controlling-rgb-led-matrix-with-shift.html
  • But basically you should get the basics working before trying my library, make sure you can turn on LEDs one by one, understand the basics, and then you can use my library which will give you much faster access to your matrix while offering a GFX graphical library on top.

    You can look at the results here:




    The original Adafruit::GFX library doesn't support multi color bitmaps, but I added support for it here: https://github.com/adafruit/Adafruit-GFX-Library/pull/39

    After doing the above, I went to add support for Tricolor Matrices, which was not much work, except for adding those 2 bits:

  • allowing shift registers to be wired to rows in reverse order when it makes wiring easier
  • 3 colors at 16pwm values and 40Hz runs against the speed limits of an arduino nano v3
  • My tricolor matrix had a common anode which was opposite from the bicolor with a common cathode.
  • This was all added to my LED-Matrix library here: https://github.com/marcmerlin/LED-Matrix
    If you'd like to buy the tricolor matrix I used, here are some links:

  • specs: http://www.seeedstudio.com/depot/datasheet/2088RGBMatrix.pdf (sold here: http://www.seeedstudio.com/depot/8x8-RGB-LED-Dot-Matrix-Compatible-with-Rainbowduino-p-113.html)
  • http://www.seeedstudio.com/depot/8x8-RGB-LED-Matrix-Square-LED-Dot-p-1730.html seems to be common cathode (the opposite)
  • This is the same matrix I used, sold by sparkfun: https://www.sparkfun.com/products/683
  • only $5 from hobbyking
  • Again, the pictures don't do a good job showing the PWM values because of the CCD trying to capture a consistent amount of light. Also, anything close to white uses all 3 LEDs, this draws too much current from my arduino on the common anode. Before I add FETs or ways to improve current per line, it's still good enogh for demos. This setup uses 2 shift registers for 16 pins (blue and red), while green is connected directly to 8 pins, and 8 pins for common anode (which is where the current for 3 LEDs at once is lacking):



    generating circles with the Adafruit::GFX library
    generating circles with the Adafruit::GFX library


    Here's a video demo:

    Links to other pages about this topic:

  • http://learnpic32.blogspot.co.nz/2014/06/controlling-rgb-led-matrix-with-shift.html
  • http://francisshanahan.com/index.php/2009/how-to-build-a-8x8x3-led-matrix-with-pwm-using-an-arduino
  • http://www.instructables.com/id/64-pixel-RGB-LED-Display-Another-Arduino-Clone
  • http://www.seeedstudio.com/wiki/60mm_square_8*8_LED_matrix_-_super_bright_RGB
  • https://www.sparkfun.com/tutorials/201
  • Sparkfun offers a hardware backpack: https://www.sparkfun.com/products/760 with code here: https://github.com/fornellas/SFRGBLEDMatrix
  • http://playground.arduino.cc/Main/LEDMatrix
  • 2013/09/14 Arduino Training and Hacking at Google
    π 2013-09-14 00:00 in Arduino, Google
    I was able to join an arduino 101 class at Google today. Ok, I wasn't an arduino neophyte, but there are a few useful things I learned during the class, and more importantly got to hack on new IO devices (I2C LCD and I2C LED matrix) which I had never interacted with before, as well as with an IR distance sensor which has pluses I was not aware of compared to the ultrasonic sensors.

    I had good time hacking with this, and in the end was able to make a game where you keep a ball inside the square with an accelerometer while another person can adjust the game speed with the IR sensor. When you lose, you get appropriate sound and screen animation (doesn't look like much, but this is usually what takes the most coding time).

    coworkers at work :)
    coworkers at work :)

    my first try
    my first try

    someone made an almost working pong game
    someone made an almost working pong game

    another keep the ball in the square game
    another keep the ball in the square game

    My finished device in smal form factor fitting on top of the arduino
    My finished device in smal form factor fitting on top of the arduino

    Here's my demo to my coworkers, using my external clean power supply:

    And the same thing in a small form factor, using the noisy arduino voltage ref (this is why it's moving so much in the init phase, despite no input). I'll have to do some analog electronics to clean that up:

    This was definitely time well spent and a good learning experience.

    2012/01/24 Much Improved Pebble v2 Aiko Demo Code
    π 2012-01-24 00:00 in Arduino
    TL;DR: Get code here: https://github.com/marcmerlin/aiko_pebble_v2

    Note, you will need the LiquidCrystal_SR_LCD3 driver from the NewLiquidCrytal Library.

    You will also need the Aiko Library: https://github.com/geekscape/aiko_arduino .

    Pebble v2 requires at least the IDE 0.23 (untested) but 1.0 or better is recommended. The code is of course arduino 1.0 compatible.

    At the LCA 2012 Arduino Miniconf, we got to build a new toy, a Freetronics Pebble v2 (schematics here). This was a refresh of the Pebble V1 (schematics here) which was the target of the very first arduino miniconf I missed in 2010.

    This new Pebble had even more hardware to program against and was a much more compact design due to the use of a bunch of SMT parts (actually there are 2 arduinos on the board, one is dedicated to usb/serial communications, removing the need for an ftdi chip).

    Like good hacking projects and conferences, the design and software were improved until the last minute, and Andy worked all night before the conf to get us his demo code (along with bits from Luke and others).
    Andy wrote the very cool aiko event handler for arduino. You give it a list of callback functions and it'll do its best to call them on the interval you gave it (interval in milliseconds). For arduino folks, with Aiko, code looks like this:

    void setup(void) {
      Serial.begin(DEFAULT_BAUD_RATE);
      // Call LCD init early so that others can write to it.
      lcdInitialize();
    

    Events.addHandler(clockHandler, 1000); Events.addHandler(lightHandler, 1000); // Aim for 250 ms Events.addHandler(rotaryEncoderHandler, 100); Events.addHandler(serialHandler, 30); // Sufficient for 38,400 baud Events.addHandler(temperatureHandler, 1000); // Aim for 250 ms Events.addHandler(touchPanelHandler, 250); // Aim for 50 ms Events.addHandler(rgbLedFadeHandler, 10); // Can run slower. // Call LCD last so that it can display variables that just changed. Events.addHandler(lcdHandler, 1000); // Aim for 100 ms }

    void loop(void) { Events.loop(); }

    So Andy got us working code to test our hardware, but of course it wasn't fully optimized (hell, code never is). So, that gave me a chance to do some arduino programming to see what could be improved. It was a good learning experience.

    After a bunch of work, here is what I was able to do:

  • I happened to have RGB LED demo code I had taken a while to write over Xmas (nice transitions that I went through the trouble of writing so they would work with an Aiko event handler), so I did a bit more hacking to refine the code and plugged it in.
  • The rotary button was being polled every millisecond to catch which was it was turning. First I figured that every 5ms was probably enough, but thanks to sample code from Brett Downing, I was able to write a handler using hardware interrupts on input pin state changes (something I knew nothing about, so it was a good learning experience).
  • Then this brings us to the LCD handler. I had some grand view of writing a popup menu that would let you configure the code at runtime, but that meant a lot of LCD code. I knew arduino had a nice LiquidCrystal library, but it did not work with the shift register setup in the Pebbles. Long story short, I wrote a plugin for the Pebble/LCD3Wires shift register setup in the Pebble. This demo requires this new library (LiquidCrystal_SR_LCD3) to do its work.
  • Here is the end result:

    Again, the code: https://github.com/marcmerlin/aiko_pebble_v2

    Here's a quick man page :)

  • The 4th line shows the color that the RGB LED is changing towards
  • LED 6 means that the color change delay factor is 6 (lower means faster color changing)
  • 3 in LED 6/3 is by how much the color brightness is reduced (clips the color values so that they arne't too bright, mostly useful in dark rooms or when taking pictures).
  • LCD 80 is the analog PWM value for the LCD backlight (higher is brighter).
  • A few custom characters are displayed to show use of the custom character support brought by LiquidCrystal_SR_LCD3

  • pop up menu with selection cursor
    pop up menu with selection cursor

    backlight menu
    backlight menu

    LED color change delay menu
    LED color change delay menu

    Note that I as read on http://www.circuitsathome.com/mcu/rotary-encoder-interrupt-service-routine-for-avr-micros and have seen with multiple decoding errors in my rotary encoder test code (shown below), it is probably a good idea to add a couple of small caps around the encoder's feet:


    And that's it folks, that was fun :)

    Oh, actually I also made a repository of small demo code I wrote for the Pebble v2: https://github.com/marcmerlin/pebble_v2_demos .

  • Full_LiquidCrytal_Demo: This is my NewLiquidCrystal demo code writing for the 20x4 LCD on the Pebble V2.
  • InterruptEncoder_test: This is the standalone/debug interrupt code I used to test the rotary button interrupt code.
  • LCD3WireExample: This allows using the deprecated http://arduino.cc/playground/Code/LCD3wires library with the Pebble v2 (this was just to try it out, there is no reason to use this library, you should be using NewLiquidCrystal's LiquidCrystal_SR_LCD3 library instead: http://marc.merlins.org/perso/arduino/post_2012-01-23_LiquidCrystal-driver-support-LCD3Wire-hardware-_pebble-and-others_.html ).
  • performanceLCD: This is a port of Fernando's LCD example for Pebble v2.
  • 2012/01/23 LiquidCrystal driver support LCD3Wire hardware (pebble and others)
    π 2012-01-23 00:00 in Arduino
    TL;DR: Get code here.

    All the code is arduino 1.0 compatible

    After coming back from the Arduino Miniconf at Linux.conf.au, I ended up with a freshly soldered freetronics pebble v2.

    Like the Pebble V1 (schematics here), it uses MC14094 8 bit shift register to drive the LCD using only 3 wires instead of 6 or more.

    The Pebble designers thankfully used the same shift register wiring than shown on the LCD3wire page on arduino playground. However, the code that came with it only had limited functionality for talking to the LCD, and the code on the LCD3wires page is also limited in functionality (on top of being incompatible with arduino 1.0).

    So, I ended up finding Francisco Malpartida's cool work on virtualizing the stock arduino LiquidCrystal library (very featureful and optimized timings). In turn, Ragnar used that codebase to design his own shift register library for 2 or 3 wires.

    Ragnar's wiring and code is somewhat complex because it exploits some interesting hacks:

  • it is designed to work with cheaper non latching shift registers.
  • it can be made to work with just 2 wires instead of 3 for non latching shift registers.
  • because of the design, the code is less obvious and exploits some tricks, but it sure works :)
  • his code can work for latching shift registers, but I do not recommend using the more complicated wiring and code if you can afford 3 wires and a shift register. Just use the LCD3Wires wiring and the code from this page.
  • In other words, if you have a non latching shift register, use his code and wiring. If you have a latching shift register, you should use the code from this page and the more widespread LCD3Wires wiring.

    So, where does this bring us?
    I used Malpartida and Ragnar's work to make an LCD3Wire hardware driver for the NewLiquidCrystal Library. This brings full library support to the pebbles as well as other folks who use the reference wiring from LCD3wires.

    I called the new library NewLiquidCrystal in the hopes that it will become the new de facto library in standard arduino one day. My code is here: https://github.com/marcmerlin/NewLiquidCrystal and includes the new LiquidCrystal_SR_LCD3 driver I wrote. To be clear, all the code came from Francisco Malpartida's work, I built on top of it to write my LiquidCrystal_SR_LCD3.cpp driver for LCD3Wires compatible hardware.

    I also wrote an extended LiquidCrystal Demo which should work on all liquidcrystal supported devices (baring the character count).



    Here is a demo of my popup menu code that works with a rotary button (cursor showing what is currently selected if you click on it)


    I'm now working with Francisco to get my code included in his tree, and if we're lucky that code may eventually get included in the standard arduino libraries as a faster and more flexible LiquidCrystal replacement.

    2011/12/12 GCC-AVR-4.5.3-2 Breaks Arduino NewSoftSerial
    π 2011-12-12 00:00 in Arduino
    Dear Google, please index this.

    TL;DR: gcc-avr 4.5.3 breaks Arduino NewSoftSerial on 328p. I had to downgrade back to 4.3.5.

    Full story:
    I had my arduino mobsendat board (328P based) working fine and after uploading some changes, it startsending a few of my characters over my Xbee, mixed with garbage. Most characters actually seemed lost.

  • https://github.com/lukeweston/RocketInstrumentation/blob/master/RocketInstrumentation-board.png
  • https://github.com/lukeweston/RocketInstrumentation/blob/master/RocketInstrumentation-schematic.png
  • In other words, I got less traffic than I should, a few were original characters, and some were garbage on a board and Xbee that were sending traffic at 38,400bps just fine for the last year.

    I used my xprotolab to decode the sending pin on the xbee directly to rule out RF issues, and I see the garbage there too. If you want to know what I mean, look at the last picture on http://www.gabotronics.com/product-info/xprotolab-pictures.htm

    So I was bit confused. The Xbee worked fine separately from the board and the serial bits getting to the xbee pins were damaged before they were sent on a simple program like this:

    #include <NewSoftSerial.h>
    

    const int XBEE_SLEEP = 8; // pin 14

    NewSoftSerial mySerial = NewSoftSerial(2, 3);

    void setup(void) { Serial.begin(38400); mySerial.begin(38400); // Switch pin to digital mode with pullup. pinMode(XBEE_SLEEP, OUTPUT); digitalWrite(XBEE_SLEEP, LOW); while (1) { Serial.println("AB12"); mySerial.println("AB12"); delay(1000); } }

    void loop(void) { }

    Arduino IDE is 0.22ubuntu0.1 on ubuntu oneiric. I thought that maybe an update to the arduino IDE broke it when I went from ubuntu marverick/natty to oneiric, but that wasn't it.

    Then I thought that maybe I damaged my hardware (maybe the clock/crystal is messed up, but then I suppose serial over USB wouldn't work either, and it does work), or if upgrading ubuntu recently broke NewSoftSerial in some subtle way, but I verified I had NewSoftSerial 10, and upgrading to 11 beta did not help.

    This is where it got wild: if I listened to the serial traffic going to the xbee from NewSoftSerial (I had version 10), and if I used the RX UART decoding pin of my Xprotolab, it could see the traffic ok. If I used the TX pin on the Xprotolab, then the same traffic mostly looked like garbage (actually most characters were lost). Putting 2 stop bits did not help.

    I talked to Gabriel Anzziani who made the Xprotolab and he said 'The RX and TX decoding are done differently in the Xprotolab. The RX is done by the XMEGA hardware, and the TX is done in firmware.'

    So clearly, there was a timing issue in what NewSoftSerial was doing at 38400 even though it had worked with the same NewSoftSerial library for about a year and NewSoftSerial 11 did not help.

    So, out of desperation, I took the nfs backup from my laptop before I upgraded from ubuntu maverick to ubuntu oneiric. While it was a bit hard to get the arduino IDE to work over an NFS chroot, I eventually got it to run, compile and upload my same Hello world serial program. And it worked!

    From there, it took a binary search to pin this down to the gcc-avr upgrade.

    gandalfthegrey:/var/local/src/arduino# dpkg -i gcc-avr-4.3.5-1.deb
    dpkg: warning: downgrading gcc-avr from 1:4.5.3-2 to 1:4.3.5-1.
    Yes, that really was the fix :(

    My guess is that the new gcc-avr changes some compilation timings/optimizations in a way that NewSoftSerial breaks :(


    More pages: April 2017 January 2017 February 2016 January 2015 September 2013 January 2012 December 2011 May 2011 January 2011