Category: Arduino

Arduino compatible designs and projects.

  • There is no bullet list like MY Bullet list

    (Notes to myself #rethinkeverything)

    Switch hands

    • Move the pain 
    • Rewire the brain

    It’s your data…

    • Hand Copy it in Triplicate.
    • If its social then scrape it and automate it. God knows they do.

    It’s your work.

    • They can’t own what you learn.
    • Redact and copy your notes in Triplicate.
    • Create/test and share open source gists/solutions
    • Make work pathways to give back to the community
    • If you have to learn it you best use it at home (lxd5/ansible/jellyfish/usw)

    Work on one less thing (simplify).

    • Every convenience is a point of failure or an attack surface.
    • Git does not need to look good to be usefull. (–gitea, –gitlab, ++bare-git+hooks/mirrors)
    • — Twitter
      • with or without musk
      • also #fuckthatguy).
      • If your content is usefull it will recieve the appropriate tweets, links, usw.
      • and if it doesnt the internet is fundamentally broken.
    • If your wysywig is so unusable you don’t “blog” Throw it away. (–wordpress) 

    Home is where the heart is.

    • Don’t let pi/routers do server/container work.
      • PiHole (filtering dns)
      • dhcp
      • look at virtualized routing
    • If you can’t netboot off of it is it really your network.
      • Same goes for centralized management (ldap).
      • dhcp
      • tftp
      • iscsi
    • All active work behind at least one firewall.
      • Automate pushes (including this site).
      • Streamline/cleanup html generation
      • It should also be replicated in at least one other location

    Let’s go to your place.

    • Ticketing systems should be more like distributed punchnotecards. –trac
    • You shouldnt be giving out XXX bucks a month to post your public images so they can be “distributed”
      • flicker free
      • multi homed

    Just because you have source control doesnt mean it’s all code

    • use markdown/git for most things.
    • but focus on the english.

    Work imitates life

    (What problems are we trying to solve)

    • Minimize technical debt both past and future.
    • Disentangle the various interconnected pieces and dependencies
    • Automate as much as possible
    • Document what is to be done. (Specification and sample implimentation)
    • Experience based stepwise refinement.
    1. See: Tufte’s critiq of power point.
    2. “as code” is only as good as the management understanding of the job of the people actually write and maintain it minus corporate whims, the abuse of executive privilege, and cultural constraints..
  • FIDLAR.

    In our last post we talked about wanting explore the use of two I2C based io expanders in an old school application. If it werent for the fact that there was a readymade lcd library for the mcp23017 I would have swapped the io expanders. No Pull-ups, No Pulldowns and no decent documentation on the circuitpython libraries makes the AW9523 a sucky choice for an old school keyboard matrix. But Hey, F**k It Dog. Life’s A Risk. We are gonna make do with what we have.

    Looking under the keyboard membrane and tracing the connectors we can get the following key map under a 4×12 array (16 pins).

       0123456789A(10)B(11)
       --------------------
    0) *# ZXCVBNM/    <STOP>
    1) -LASDFGHJK<N/C><ENTER>
    2) 0912345678<BS> <START>
    3) POQWERTYUI<CAN><DIAL>
    *#ZXCVBNM/STOP
    LASDFGHJKN/CENTER
    0912345678<—-START
    POQWERTYUICANCELDIAL

    Of course for this to work we needed to solder 10k pull up resistors on all but the last 4 pins (8-11). This was relatively straightforward since there is a strip of connectors to VIN on the board. Still, kind of a pain. On the other hand I have reals of 10k resistors and I guess I have time.

    Here is a simple circtuitpython program which presents a prompt and then puts characters scanned by the keyboard onto the display.

    import time
    import board
    import busio
    import adafruit_character_lcd.character_lcd_rgb_i2c as character_lcd
    import adafruit_aw9523
    
    keymap=[]
    keymap.append('*# ZXCVBNM/\001')
    keymap.append('-LASDFGHJK\r\n')
    keymap.append('0912345678\010\002')
    keymap.append('POQWERTYUI\030\004')
    
    lcd_columns = 24
    lcd_rows = 2
    i2c = busio.I2C(board.SCL, board.SDA)
    lcd = character_lcd.Character_LCD_RGB_I2C(i2c, lcd_columns, lcd_rows)
    lcd.message = "PiTerm 1986 v0.0\nOk >"
    
    aw = adafruit_aw9523.AW9523(i2c)
    row_pins = [aw.get_pin(8),aw.get_pin(9),aw.get_pin(10),aw.get_pin(11)]
    for pin in row_pins:
       pin.switch_to_output(value=True)
    
    col_pins = [aw.get_pin(0),aw.get_pin(15),aw.get_pin(14),aw.get_pin(13),
                aw.get_pin(12),aw.get_pin(7),aw.get_pin(6),aw.get_pin(5),
                aw.get_pin(4),aw.get_pin(3),aw.get_pin(2),aw.get_pin(1)]
    
    for pin in col_pins:
       pin.switch_to_input(value=True)
    
    
    old_row=0;
    for pin in row_pins:
        pin.value=1
    
    switch_state = [[0,0,0,0,0,0,0,0,0,0,0,0],
                    [0,0,0,0,0,0,0,0,0,0,0,0],
                    [0,0,0,0,0,0,0,0,0,0,0,0],
                    [0,0,0,0,0,0,0,0,0,0,0,0]
                   ]
    while True:
        for r in range(4):
            row_pins[old_row].value=1
            row_pins[r].value=0
            old_row=r
            for c in range(12):
                if (col_pins[c].value==0 and switch_state[r][c]==0):
                    switch_state[r][c]=1
                    print(keymap[r][c])
                    lcd.message+=keymap[r][c]
                if (col_pins[c].value==1 and switch_state[r][c]==1):
                    switch_state[r][c]=0
        time.sleep(0.01)  # debounce

    References

  • E-Paper is Slow.

    I was going to explain how we got here but. Nah. It is what it is.

    This image has an empty alt attribute; its file name is IMG_3633-1024x768.jpgThis image has an empty alt attribute; its file name is IMG_3632-1024x768.jpg
    #---------------------------------------------------------------epaperisslow.py
    # playing around with 2.13" HD mono pi hat.
    # references adafruit example code.
    # screen drawing takes 9-10 seconds per update.
    
    
    from datetime import datetime
    
    def TimeString ():
        return datetime.now().strftime("%H:%M")
        
    import time
    import busio
    import board
    from digitalio import DigitalInOut, Direction
    
    from PIL import Image
    from PIL import ImageDraw
    from PIL import ImageFont
    from adafruit_epd.epd import Adafruit_EPD
    from adafruit_epd.ssd1675b import Adafruit_SSD1675B  
    import math
    import random
    
    
    # create two buttons
    switch1 = DigitalInOut(board.D6)
    switch2 = DigitalInOut(board.D5)
    switch1.direction = Direction.INPUT
    switch2.direction = Direction.INPUT
    
    # create the spi device and pins we will need
    spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
    ecs = DigitalInOut(board.CE0) ## check back on this
    dc = DigitalInOut(board.D22)
    rst = DigitalInOut(board.D27)
    busy = DigitalInOut(board.D17)
    
    # give them all to our driver
    display = Adafruit_SSD1675B(
        122,
        250,
        spi,  # 2.13" HD mono display (rev B)
        cs_pin=ecs,
        dc_pin=dc,
        sramcs_pin=None,
        rst_pin=rst,
        busy_pin=busy,
    )
    display.rotation = 1
    
    # Create blank image for drawing.
    # Make sure to create image with mode '1' for 1-bit color.
    width = display.width
    height = display.height
    lightimage = Image.new("RGB", (width, height))
    darkimage = Image.new("RGB", (width, height))
    
    WHITE = (0xFF, 0xFF, 0xFF)
    BLACK = (0x00, 0x00, 0x00)
    print("clearing display")
    # clear the buffer
    display.fill(Adafruit_EPD.WHITE)
    # clear it out
    display.display()
    
    # Get drawing object to draw on image.
    light = ImageDraw.Draw(lightimage)
    dark = ImageDraw.Draw(darkimage)
    # empty it
    light.rectangle((0, 0, width, height), fill=WHITE)
    dark.rectangle((0, 0, width, height), fill=BLACK)
    print("drawing box")
    
    # Draw an outline box
    light.rectangle((1, 1, width - 2, height - 2), outline=BLACK, fill=WHITE)
    # Draw some shapes.
    # First define some constants to allow easy resizing of shapes.
    padding = 5
    shape_width = 30
    top = padding
    bottom = height - padding
    # Move left to right keeping track of the current x position for drawing shapes.
    x = padding
    
    # Load default font.
    
    font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 80)
    
    text_origin=(7,top+15)
    light.text(text_origin, TimeString(), font=font, fill=BLACK)
    dark.text(text_origin, TimeString(), font=font, fill=WHITE)
    
    print("entering the loops")
    
    #display.image(darkimage)
    #display.display()
    
    old_ticks = time.monotonic() - 50.0
    image2display=darkimage
    
    while True:
        ticks = time.monotonic()
        # if programmer is bored: move this section to an interrupt
        if not switch1.value:
            print("Switch 1")
            image2display=lightimage
            display.image(image2display)
            display.display()
            #No point in debouncing after the display takes 9 seconds
            #while not switch1.value:
            #    time.sleep(0.01)
    
        if not switch2.value:
            print("Switch 2")
            image2display=darkimage
            display.image(image2display)
            display.display()
            #No point in debouncing after the display takes 9 seconds
            #while not switch2.value:
            #    time.sleep(0.01)
    
        # print( ticks - old_ticks)
    
        # Update the time on both dark and light images.
        if(( ticks  - old_ticks) >= 50.0):
            #current_time=datetime.now().strftime("%H:%M  ")
            print("updating "+TimeString())
            light.rectangle((0, 0, width, height), fill=WHITE)
            dark.rectangle((0, 0, width, height), fill=BLACK)
            light.rectangle((1, 1, width - 2, height - 2), outline=BLACK, fill=WHITE)
            light.text(text_origin,TimeString(),font=font, fill=BLACK)
            dark.text(text_origin,TimeString(), font=font, fill=WHITE)
            display.image(image2display)
            display.display()
            old_ticks=time.monotonic()
    
    feurig@figaro:~/raspi-python-playground $ python3 epaperisslow.py 
    clearing display
    drawing box
    entering the loops
    updating 08:06
    Switch 1
    Switch 2
    Switch 1
    updating 08:07
    updating 08:08
    ^C
    feurig@figaro:~/raspi-python-playground $ cat /etc/rc.local
    #!/bin/sh -e
    # turn off the on board led and start the clock
    echo 0 > /sys/class/leds/led0/brightness
    python3 /home/feurig/raspi-python-playground/epaperisslow.py
    exit 0
    
  • I should drop out more often.

    Things are different.

    In the 2+ years after I gave up on making things for a living a lot of things have changed. Things on my personal radar….

    • The price points for adding wifi for Q<1000 is not $15. It’s $3.
    • The Midi Manufacturers Association finally put 3.3v into the hardware standard.
    • The Non compete agreements with some of the most egregious underpaying jerks that I have ever contracted with have expired….

    So….

    Watch this space…..

  • Making Stephen Wright’s Light Switch with the Adafruit Huzzah!

    23439940833_31be1e9c50_o

     

    Things are Different

    In 2012 I was struggling to put together a stm32 based wireless datalogger using leaflabs libmaple and a $20 wifi module. I had to write most of the code myself because libmaple was based on arduino-0022 and most of the wifi libraries made extensive use of the new classes available after arduino 1.xx (String for instance). It was painful and in the end the project was a complete failure except that I had a premade platform to make an art piece called Stephen Wrights Light Switch.

     

    8346730548_dede0fa72e_n img_0935_23439975343_o

    Nowadays you can get an Arduino capable wifi module for less than 10 bucks.

    Huzzah!

    (look it up on the internets!)


    /*-----------------------------------StephenWrightsLightSwitch.ino
     This is a hack of the provided WifiClient example.
     This is free software (BSD License)
     (C) Donald Delmar Davis , SuspectDevices.
    
     ---------------------------------------------------------------*/
    
    
    #include <ESP8266WiFi.h>
    
    
    #define SWITCH_OFF 1
    #define SWITCH_ON 0
    #define LED_OFF 0
    #define LED_ON 1
    
    
    const char* ssid = "MYWIFI";
    const char* password = "MYSECRET";
    const char* host = "www.suspectdevices.com";
    const int httpPort = 80;
    
    const char* offstate = "OFF";
    const char* onstate = "ON";
    
    #ifdef ESP8266_DEV_BOARD
    const int switchPin = 4;
    const int ledPin = 5;
    #else
    const int switchPin = 4;
    const int ledPin = 5;
    #endif 
    /*
     global variables
    */
    
    bool newSwitchValueFlag = false;
    bool oldSwitchValue = SWITCH_OFF;
    bool lightValue = SWITCH_OFF;
    
    
    /*---------------------------------------------------setup()
    
    */
    void setup() {
     bool flipFlop = SWITCH_OFF;
    
     Serial.begin(115200);
     pinMode(switchPin, INPUT_PULLUP);
     pinMode(ledPin, OUTPUT);
     digitalWrite(ledPin, LED_ON);
     delay(10);
    
     // We start by connecting to a WiFi network
    
     Serial.println();
     Serial.println();
     Serial.print("Connecting to ");
     Serial.println(ssid);
     WiFi.begin(ssid, password);
    
     while (WiFi.status() != WL_CONNECTED) {
     flipFlop = !flipFlop;
     digitalWrite(switchPin, flipFlop);
     delay(500);
     Serial.print(".");
     }
    
     digitalWrite(ledPin, LED_OFF);
    
     Serial.println("");
     Serial.println("WiFi connected");
     Serial.println("IP address: ");
     Serial.println(WiFi.localIP());
    
    }
    
    /*-------------------------------------------------------------------------loop()
    
    */
    void loop() {
     
     bool newSwitchValue;
     
     newSwitchValue = (digitalRead(switchPin)==SWITCH_ON);
     
     Serial.print("Switch="); Serial.println(newSwitchValue?"ON":"OFF");
     
     if (newSwitchValue != oldSwitchValue) {
     newSwitchValueFlag = true;
     } else {
     newSwitchValueFlag = false;
     }
     
     Serial.print("connecting to ");
     Serial.println(host);
    
     // Use WiFiClient class to create TCP connections
     WiFiClient client;
     if (!client.connect(host, httpPort)) {
     Serial.println("connection failed");
     return;
     }
    
     // We now create a URI for the request
     String url = "/art2013/settheswitch/";
     if (newSwitchValueFlag) {
     url += "?state=";
     url += newSwitchValue ? onstate : offstate;
     oldSwitchValue=newSwitchValue;
     }
    
     Serial.print("Requesting URL: ");
     Serial.println(url);
    
     // This will send the request to the server
     client.print(String("GET ") + url + " HTTP/1.1\r\n" +
     "Host: " + host + "\r\n" +
     "Connection: close\r\n\r\n");
     
     for (int t = 8; t > 0 && !client.available(); t--)
     delay(100);
    
     // Read all the lines of the reply from server and print them to Serial
     while (client.available()) {
     String line = client.readStringUntil('\r');
     if (line.lastIndexOf("ON") >= 0) {
     Serial.println("FOUND AN ON!!!");
     lightValue = SWITCH_ON;
     } else {
     lightValue = SWITCH_OFF;
     }
    
     Serial.print(line);
     }
    
     digitalWrite(ledPin, lightValue ? LED_ON : LED_OFF);
    
     Serial.println();
     Serial.println("closing connection");
     // client.close();
    
    }
    
    
  • The Adafruit Huzzah and the Sparkfun Esp8266 dev board.

    Background.

    I was asked to put together a 2 day class on the internet of things at PNCA so I suggested that we try out the Adafruit huzzah.  while I was looking for it I came across the Sparkfun Esp8266 “thing” and the Esp8266 dev board. I used the Sparkfun Esp8266 dev board to implement a light socket that queried the internet for its State.

    IMG_1259

    Connections

    The most important thing you can do with your Huzzah is to make sure you have at least 250 ma of power available to the wifi part of the module. There is nothing more frustrating than having everything worked as advertised until you turn the radio on. The Sparkfun boards have usb power which is good enough. The Huzzah has an on board regulator for both external battery and can be powered by USB’s 5v and it detects an d uses whichever is greater.

    After working through some code on the Huzzah with the students, I went to the Hardware store and purchased and externally mounted light socket, I had brought with me a solid state relay from my bench pile. For all practical purposes an SSR can be thought of as an LED. In fact the SSR that I chose did not have a current reducing circuit and I let the smoke out of the first one. To power the board I purchased a mini usb charger which without the external casing fit fine in the enclosure.

    IMG_1256

    The Server from ByteMe 2013

    The web server for the afru show is still presenting the state of Stephen Wrights Light Switch from the AFRU Gallery’s annual Byte Me show in 2013. The code to present the state is a small pile of python. The most important part is the 3 non standard ways to tell your browser to stop caching the data since no-one seems to follow the established standards (..that means you safari..)

    ...$ cat index.wsgi 
    import webapp2
    import sqlite3
    
    class MainPage(webapp2.RequestHandler):
        def get(self):
    
        con=sqlite3.connect('/home/newcourse/suspectdevices/www/art2013/swls/swls.db')
        cur=con.cursor()
        
        cur.execute("select state from switch")
        swstate=cur.fetchone()[0]    
        self.response.headers['Content-Type'] = 'text/plain'
        self.response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
        self.response.headers['Pragma'] = 'no-cache'
        self.response.headers['Expires'] = '0'
        self.response.out.write(swstate)
    
    application = webapp2.WSGIApplication([('/art2013/swls/index.wsgi', MainPage)],
                                  debug=True)
    
    

    Creating the Light Socket using the esp8266 dev board

     
    The arduino code for creating the light switch is remarkably simple. After setting up the wifi connection the device repeatedly does does an http get which returns the header information and a body containing either ON or OFF. Since the standard headers do not contain the word ON we look for that using the arduino String class’ indexOf method.

     

    /*----------------------FrauleinMartinaFranksLightSocket.ino
     This is a hack of the provided WifiClient example.
     This is free software (BSD License)
     (C) 2015 Donald Delmar Davis , SuspectDevices.
    ----------------------------------------------------------*/
    
    
    #include <ESP8266WiFi.h>
    
    /*
     Declarations and constants
    */
    
    #define ESP8266_DEV_BOARD 1
    
    #define SWITCH_OFF 1
    #define SWITCH_ON 0
    #define LED_OFF 0
    #define LED_ON 1
    #define RELAY_OFF 0
    #define RELAY_ON 1
    
    
    const char* ssid = "MYSSID";
    const char* password = "myWifiPassword";
    const char* host = "www.suspectdevices.com";
    const int httpPort = 80;
    
    const char* offstate = "OFF";
    const char* onstate = "ON";
    #ifdef ESP8266_DEV_BOARD
    // esp8266 dev board 0,4,5(LED) and 14 are available as General Purpose pins
    // on board led is at pin 5
    // avoid pin 15 messes with downloading
    const int switchPin = 4;
    const int ledPin = 5;
    const int relayPin = 2;
    #elseif defined(ADAFRUIT_HUZZAH)
    const int switchPin = 4;
    const int ledPin = 13;
    const int relayPin = 2;
    #else 
    const int switchPin = 4;
    const int ledPin = 13;
    const int relayPin = 2;
    #endif 
    /*
     global variables
    */
    
    bool oldSwitchValue = SWITCH_OFF;
    
    
    /*-----------------------------------------------------------setup()
    
    */
    void setup() {
     bool flipFlop = SWITCH_OFF;
    
     Serial.begin(115200);
     pinMode(switchPin, INPUT_PULLUP);
     pinMode(ledPin, OUTPUT);
     digitalWrite(ledPin, LED_ON);
     pinMode(relayPin, OUTPUT);
     digitalWrite(relayPin, RELAY_ON);
     delay(10);
    
     // We start by connecting to a WiFi network
    
     Serial.println();
     Serial.println();
     Serial.print("Connecting to ");
     Serial.println(ssid);
     WiFi.begin(ssid, password);
    
     while (WiFi.status() != WL_CONNECTED) {
     flipFlop = !flipFlop;
     digitalWrite(ledPin, flipFlop);
     delay(500);
     Serial.print(".");
     }
    
     digitalWrite(ledPin, LED_OFF);
    
     Serial.println("");
     Serial.println("WiFi connected");
     Serial.println("IP address: ");
     Serial.println(WiFi.localIP());
    
    }
    
    /*---------------------------------------------------loop()
    
    */
    void loop() {
     delay(1000);
    
     Serial.print("connecting to ");
     Serial.println(host);
    
     // Use WiFiClient class to create TCP connections
     WiFiClient client;
     if (!client.connect(host, httpPort)) {
     Serial.println("connection failed");
     return;
     }
    
     // We now create a URI for the request
     String url = "/art2013/swls/";
    
     Serial.print("Requesting URL: ");
     Serial.println(url);
    
     // This will send the request to the server
     client.print(String("GET ") + url + " HTTP/1.1\r\n" +
     "Host: " + host + "\r\n" +
     "Connection: close\r\n\r\n");
     
     for (int t = 5; t > 0 && !client.available(); t--)
     delay(100);
    
     // Read all the lines of the reply from server and print them to Serial
     while (client.available()) {
     String line = client.readStringUntil('\r');
     if (line.lastIndexOf("ON") >= 0) {
     Serial.println("FOUND AN ON!!!");
     oldSwitchValue = SWITCH_ON;
     } else {
     oldSwitchValue = SWITCH_OFF;
     }
     Serial.print(line);
     }
    
     digitalWrite(ledPin, oldSwitchValue ? LED_ON : LED_OFF);
     digitalWrite(relayPin, oldSwitchValue ? RELAY_ON : RELAY_OFF);
    
     Serial.println();
     Serial.println("closing connection");
    
    }
    
    

    IMG_1254

    References

  • Arduino code for Happy Accident 3

    /* Ping))) Sensor

    This sketch reads a PING))) ultrasonic rangefinder and returns the
    distance to the closest object in range. To do this, it sends a pulse
    to the sensor to initiate a reading, then listens for a pulse
    to return. The length of the returning pulse is proportional to
    the distance of the object from the sensor.

    The circuit:
    * +V connection of the PING))) attached to +5V
    * GND connection of the PING))) attached to ground
    * SIG connection of the PING))) attached to digital pin 7

    http://www.arduino.cc/en/Tutorial/Ping

    created 3 Nov 2008
    by David A. Mellis
    modified 30 Aug 2011
    by Tom Igoe

    This example code is in the public domain.

    */
    byte pattern[]={
    B11111111,
    B01111111,
    B00111111,
    B00011111,
    B00001111,
    B00000111,
    B00000011,
    B00000001,
    B00000000,

    };
    byte pattern2[]={
    B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
    B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
    B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
    B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
    B00100010,B00100010,B11011100,B10101100,B10101110,B01010000,B00000011,B10101000,B10110101,
    B01010110,B10101110,B10010010,B11011100,B10101100,B01010000,B10101110,B00100010,B10001010,
    B00100010,B11011100,B10101100,B10101110,B01010000,B00000011,B10101000,B01010110,B10011010,
    B10101110,B10010010,B01101100,B10101100,B01010000,B10101110,B00100010,B00010010,B01100101,
    B11011100,B10101100,B10101110,B01010000,B00000001,B10101000,B01010110,B10101110,B10100000,
    B00100010,B00100010,B11011100,B10101100,B10101110,B01010000,B00000011,B10101000,B01101001,
    B01010110,B10101110,B10010010,B11011100,B10101100,B01010000,B10101110,B00100010,B10100110,
    B00100010,B11011100,B10101100,B10101110,B01010000,B00000011,B10101000,B01010110,B10100110,
    B10101110,B10010010,B01101100,B10101100,B01010000,B10101110,B00100010,B00010010,B10110001,
    B11011100,B10101100,B10101110,B01010000,B00000001,B10101000,B01010110,B10101110,B11101101,
    B10010010,B01101110,B10101100,B01010000,B10101110,B00000000,B00000000,B00000000,B00100010,
    B00100010,B00100010,B11011100,B10101100,B10101110,B01010000,B00000011,B10101000,B10110101,
    B11011100,B10101100,B10101110,B01010000,B00000001,B10101000,B01010110,B10101110,B10100000,
    B00100010,B00100010,B11011100,B10101100,B10101110,B01010000,B00000011,B10101000,B01101001,
    B01010110,B10101110,B10010010,B11011100,B10101100,B01010000,B10101110,B00100010,B10100110,
    B00100010,B11011100,B10101100,B10101110,B01010000,B00000011,B10101000,B01010110,B10100110,
    B10101110,B10010010,B01101100,B10101100,B01010000,B10101110,B00100010,B00010010,B10110001,
    B11011100,B10101100,B10101110,B01010000,B00000001,B10101000,B01010110,B10101110,B11101101,
    B10010010,B01101110,B10101100,B01010000,B10101110,B00000000,B00000000,B00000000,B00100010,
    B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
    B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,

    };
    #define NUM_REGISTERS 8
    #define MAX_PATTERN (((sizeof(pattern2)/sizeof(byte))/NUM_REGISTERS) -2 )
    //#define MAX_PATTERN (sizeof(pattern2)/sizeof(byte))
    // this constant won't change. It's the pin number
    // of the sensor's output:
    const int pingPin = 7;
    #define CLOCK 12
    #define LATCH 8
    #define DATA 10
    void setup() {
    // initialize serial communication:
    Serial.begin(57600);
    pinMode(CLOCK,OUTPUT);
    pinMode (LATCH, OUTPUT);
    pinMode ( DATA,OUTPUT);
    }
    long int lastMovement=0;
    long int lastDistance=0;
    void loop()
    {
    // establish variables for duration of the ping,
    // and the distance result in inches and centimeters:
    long duration, inches, cm;
    int output,rn;

    // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
    // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
    pinMode(pingPin, OUTPUT);
    digitalWrite(pingPin, LOW);
    delayMicroseconds(2);
    digitalWrite(pingPin, HIGH);
    delayMicroseconds(5);
    digitalWrite(pingPin, LOW);

    // The same pin is used to read the signal from the PING))): a HIGH
    // pulse whose duration is the time (in microseconds) from the sending
    // of the ping to the reception of its echo off of an object.
    pinMode(pingPin, INPUT);
    duration = pulseIn(pingPin, HIGH);

    // convert the time into a distance
    inches = microsecondsToInches(duration);
    cm = microsecondsToCentimeters(duration);
    if ( cm 125)cm=125;
    if (lastDistance != cm) {
    lastDistance=cm;
    lastMovement=millis();
    }
    Serial.print(cm);
    Serial.print(" cm, ");
    output=map(cm,0,125,0,MAX_PATTERN);
    Serial.print(output);

    // Serial.print(cm);
    digitalWrite (LATCH, LOW);
    //shiftOut(DATA,CLOCK,LSBFIRST,~(1<>cm));
    //delay(1000);
    for (rn=0;rn 2000) {
    delay(60); // one thing to try. //output=MAX_PATTERN+1;
    } else {
    delay(100+random(200));
    }

    }

    long microsecondsToInches(long microseconds)
    {
    // According to Parallax's datasheet for the PING))), there are
    // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
    // second). This gives the distance travelled by the ping, outbound
    // and return, so we divide by 2 to get the distance of the obstacle.
    // See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
    return microseconds / 74 / 2;
    }

    long microsecondsToCentimeters(long microseconds)
    {
    // The speed of sound is 340 m/s or 29 microseconds per centimeter.
    // The ping travels out and back, so to find the distance of the
    // object we take half of the distance travelled.
    return microseconds / 29 / 2;
    }