by on Arduino

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

by on 8051circuitpythonRaspberry Pi

This is a snapshot of the current readme: Updates and current progress are on its github page: https://github.com/feurig/PiTerm1986

GOAL: Convert 80s style user interface ( 8031 based ADP Product: chicklet keyboard and 2×20 lcd ) to pi zero based terminal using i2c based io expanders.

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

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

Keyboard

For this we look at the AW9523 GPIO expander with 16 pins of io.

LCD/VFD

Since the LCD is a 5v circuit requiring either 8 or 12 pins we look at the Microchip MCP23017 on the Adafruit GPIO Expander Bonnet which we can wire either using both ports or one port in nibble mode.

Via : https://protostack.com.au/2010/03/character-lcd-displays-part-1/

Attaching Both Boards to the Raspberry pi.

root@somepi1:/home/feurig# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- 58 -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         

Assembly and layout.

After putting the board in the box I realized that the grey paint was conductive and that I almost let the smoke out of the pi zero. (you could smell it). So I went out and found a piece of plastic from a previous project. 

And then I was like OH SHIT I have Noritake 2×24 VFD thats a close fit..

So there’s a circuitpython library for an mcp23017 connected to an lcd. Wiring it up according to the above schematic lets us write away

root@somepi1:/home/feurig# pip3 install adafruit-circuitpython-charlcd
...
root@somepi1:/home/feurig# python3
Type "help", "copyright", "credits" or "license" for more information.
>>> import board
>>> import busio
>>> import adafruit_character_lcd.character_lcd_rgb_i2c as character_lcd
>>> 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 = "Hello\nPiTerm1986"
>>> lcd.clear()
>>> lcd.message = "PiTerm 1986 v0.0\nOk >"
>>> 

I am not thrilled about the way its wired but whatever.

References

by on Arduinocircuitpython

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

by on OpenWrt

The Ubiquity EdgeRouter Lite is my new favorite OpenWrt device. It is fast and inexpensive ($150 new) and the os is on a USB Stick. Stock Photo

Pros

  • 3 independent Gigabit network ports.
  • Serial Console
  • Cheap and still supported.
  • Stock Edge-os would work for most tasks.
  • OS on a USB-stick easiest backup and install EVER.
  • 512 K of memory.

Cons (some assembly required)

  • Because the stock usb stick and (unused) flash is only 4K LEDE considers it a 4K and are threatening to stop producing stock images after 19.07.
  • Third party usb sticks take longer to start up than the on board bootloader (U-boot) expects. So a pause and usb reset need to be configured.

How do I get set up?

Building 19.07 for the device

  • Getting the source. See LEDE documentation for dependencies.
feurig@vasily:~$ git clone https://git.openwrt.org/openwrt/openwrt.git
  • Building for the target
feurig@vasily:~$ cd openwrt/
feurig@vasily:~/openwrt$ make clean
feurig@vasily:~/openwrt$ git pull . v19.07.3
feurig@vasily:~/openwrt$ ./scripts/feeds update -a
feurig@vasily:~/openwrt$ ./scripts/feeds install -a
feurig@vasily:~/openwrt$ make menuconfig

    Target System (Cavium Networks Octeon)  --->
    Target Profile (Ubiquiti EdgeRouter Lite)  --->                                                                                   
    Target Images --------->
       [*] ramdisk  --->
       ***   Root filesystem archives ***
       [ ] cpio.gz
       [*] tar.gz
       ***   Root filesystem images ***
       [*] ext4  --->
       [ ] squashfs  ---- 
       [*] GZip images
           *** Image Options *** 
       (104) Root filesystem partition size (in MB) 
feurig@vasily:~/openwrt$ make -j8 download world
feurig@vasily:~/openwrt$ mv bin/targets/octeon/generic/openwrt-octeon-erlite-ext4-sysupgrade.tar.gz ~/firmware/
feurig@vasily:~/openwrt$ ./scripts/diffconfig.sh > ../firmware/openwrt-octeon-erlite-ext4-sysupgrade.diffconfig

Deploying the image

  • download the image from the build server to a local linux box.
feurig@colbert:~ $ scp feurig@wrt.suspectdevices.com:firmware/openwrt-octeon-erlite-ext4-sysupgrade.tar.gz .
  • Format the stick with 2 partitions (142M dos and the lemaining linux)
root@colbert:~ # fdisk -l
... On our machine, this is our disk ...
Disk /dev/sda: 7.6 GiB, 8166703104 bytes, 15950592 sectors
...
root@colbert:~ # fdisk /dev/sda
... Partition disk here ...
root@colbert:~ # fdisk -l
...
Disk /dev/sda: 7.6 GiB, 8166703104 bytes, 15950592 sectors
Disk model: USB 2.0 FD      
...
Device     Boot  Start     End Sectors  Size Id Type
/dev/sda1         2048  292863  290816  142M  c W95 FAT32 (LBA)
/dev/sda2       292864 3710975 3418112  1.6G 83 Linux
...
root@colbert:/home/feurig# mkfs.vfat /dev/sda1
root@colbert:/home/feurig# mkfs.ext4 /dev/sda2
  • copy firmware to usb stick
root@colbert:~ # mkdir scratch
root@colbert:~ # cd scratch/
root@colbert:~ # tar -xf ../openwrt-octeon-erlite-ext4-sysupgrade.tar.gz 
root@colbert:~ # mkdir root oroot kernel
root@colbert:~ # mount /dev/sda1 kernel/
root@colbert:~ # mount /dev/sda2 root/
root@colbert:~ # mount sysupgrade-erlite/root oroot -o loop
root@colbert:~ # cp sysupgrade-erlite/kernel kernel/vmlinux.64
root@colbert:~ # md5sum sysupgrade-erlite/kernel | cut -d' ' -f 1 > kernel/vmlinux.64.md5
root@colbert:~ # rsync -aHAX oroot/* root/
root@colbert:~ # umount kernel root oroot
root@colbert:~ # sync

Fixing the bootloader for standard USB Sticks.

  • If the usb stick used takes longer than the stock one to initialize the boot will fail.
don$ screen /dev/tty.usbserial 115200
...
U-Boot 1.1.1 (UBNT Build ID: 4670715-gbd7e2d7) (Build time: May 27 2014 - 11:16:22)
.
BIST check passed.
UBNT_E100 r1:2, r2:18, f:4/71, serial #: 802AA84CE978
MPR 13-00318-18
Core clock: 500 MHz, DDR clock: 266 MHz (532 Mhz data rate)
DRAM:  512 MB
Clearing DRAM....... done
Flash:  4 MB
Net:   octeth0, octeth1, octeth2
.
USB:   (port 0) scanning bus for devices... 
      USB device not responding, giving up (status=0)
1 USB Devices found
       scanning bus for storage devices...
No device found. Not initialized?                                                                                                                  0 
  • Getting the stock boot command
Octeon ubnt_e100# printenv               
bootdelay=0
baudrate=115200
download_baudrate=115200
nuke_env=protect off $(env_addr) +$(env_size);erase $(env_addr) +$(env_size)
autoload=n
ethact=octeth0
bootcmd=fatload usb 0 $loadaddr vmlinux.64;bootoctlinux $loadaddr coremask=0x3 root=/dev/sda2 rootdelay=15 rw rootsqimg=squashfs.img rootsqwdir=w mtd
...
  • Copy the bootcmd from the existing environment and add a delay and usb reset
Octeon ubnt_e100# setenv bootcmd 'sleep 10;usb reset;fatload usb 0 $loadaddr vmlinux.64;bootoctlinux $loadaddr coremask=0x3 root=/dev/sda2 rootdelay=15 rw rootsqimg=squashfs.img rootsqwdir=w mtd'
Octeon ubnt_e100# saveenv
Octeon ubnt_e100# reset

Adding Initial Configuration to build

In our deployment the router is maintained externally. For this reason direct login to the router as root is disabled and sudo enabled accounts are installed. These accounts connect using ssh keys and escallate privilages with their passwords. The root account is locked and ssh access is allowed from the wan port. The process for this is documented here

Once this is done the configuration can be saved to a tarball and added to the build under the files directory. These files are copied into the root filesystem of the target. The box then comes up pre configured and pre-hardened. One kludge used here is to add an rc.local which changes the users home directorys to be owned by them. Otherwise the ssh keys will not have the correct permissions.

Also /etc/sudoers, /etc/rc.local, and /home should be added to /etc/sysupgrade.conf. This way the configuration changes will be preserved while doing a sysupgrade

Rebuilding using a repo.

Now that we have a working pre-hardened build for our router we can adjust and repeat the build. (this example assumes that the build server has access to the repo)

feurig@vasily:~$ cd openwrt
feurig@vasily:~/openwrt$ git pull . v19.07.3
feurig@vasily:~/openwrt$ mv files /tmp/
feurig@vasily:~/openwrt$ git clone git@bitbucket.org:houselan/config.git files
Cloning into 'files'...
feurig@vasily:~/openwrt$ cp files/openwrt-octeon-erlite-ext4-sysupgrade.diffconfig .config
feurig@vasily:~/openwrt$ make defconfig
#
# configuration written to .config
#
feurig@vasily:~/openwrt$ ./scripts/feeds update -a
...
feurig@vasily:~/openwrt$ ./scripts/feeds install -a
...
feurig@vasily:~/openwrt$ make -j8 download world
feurig@vasily:~/openwrt$ mv bin/targets/octeon/generic/openwrt-octeon-erlite-ext4-sysupgrade.tar.gz ~/firmware/
feurig@vasily:~/openwrt$ ./scripts/diffconfig.sh > ../firmware/openwrt-octeon-erlite-ext4-sysupgrade.diffconfig 

References

Primary

by on e-bike

Last time the government gave me a significant amount of unexpected money I bought a sporterized mac 90 (a semiautomatic ak-47). This time I decided to join a different revolution. With a projected cap of $1200 I asked a friend to help me pick parts for converting a Yamaha 850 tripple to electric.

He remembered a conversion that he had helped with and now I have a complete but currently non running conversion of a 2003 Suzuki Bergman 650

by on ArduinoarmMaple BaconSite NewsSuspect Devices

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…..

by on ArduinoMaple Bacon

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();

}

by on Arduinoarm

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