May 212017
 

ESP8285

Espruino does not need more than 1 MB of Flash memory, so using a single chip solution with 1 MB Flash integrated like the ESP8285 seesm to be a sensible choice. And it works with Espruino just like the ESP8266 does.

The only special part is how to flash it:

esptool.py --port /dev/ttyUSB0 --baud 115200 write_flash \
--flash_mode dout --flash_size 8m \
0x0000 boot_v1.6.bin \
0x1000 espruino_esp8266_user1.bin \
0xFC000 esp_init_data_default.bin 0xFE000 blank.bin

There’s no difference when it comes to save(): only very small programs can be saved. I hope the ESP32 is better in this regard.

Mar 252017
 
STM32F4 Discovery and Espruino

Some time ago I installed Espruino on the STM32F4 Discovery board.

Here my notes:

sudo aptitude install cmake libusb-1.0-0-dev
git clone https://github.com/texane/stlink.git
cd stlink
cmake .
make
# install into /usr/local/
sudo make install
sudo ldconfig -v

How you should be able to see the STM32F4 Discovery board:

$ sudo st-info --probe 
Found 1 stlink programmers 
 serial: 563f6b06493f51521236213f 
openocd: "\x56\x3f\x6b\x06\x49\x3f\x51\x52\x12\x36\x21\x3f" 
  flash: 1048576 (pagesize: 16384) 
   sram: 196608 
 chipid: 0x0413 
  descr: F4 device

and now flash:

 
$ sudo st-flash write espruino_1v91_stm32f4discovery.bin 0x08000000                                
st-flash 1.3.1-11-g78ced6a 
2017-03-25T20:41:03 INFO src/common.c: Loading device parameters.... 
2017-03-25T20:41:03 INFO src/common.c: Device connected is: F4 device, id 0x10016413 
2017-03-25T20:41:03 INFO src/common.c: SRAM size: 0x30000 bytes (192 KiB), Flash: 0x100000 bytes (1024 KiB) in pages of 16
384 bytes 
2017-03-25T20:41:03 INFO src/common.c: Attempting to write 298872 (0x48f78) bytes to stm32 address: 134217728 (0x8000000) 
Flash page at addr: 0x08040000 erasedEraseFlash - Sector:0x6 Size:0x20000  
2017-03-25T20:41:09 INFO src/common.c: Finished erasing 7 pages of 131072 (0x20000) bytes 
2017-03-25T20:41:09 INFO src/common.c: Starting Flash write for F2/F4/L4 
2017-03-25T20:41:09 INFO src/flash_loader.c: Successfully loaded flash loader in sram 
enabling 32-bit flash writes 
size: 32768 
size: 32768 
size: 32768 
size: 32768 
size: 32768 
size: 32768 
size: 32768 
size: 32768 
size: 32768 
size: 3960 
2017-03-25T20:41:13 INFO src/common.c: Starting verification of write complete 
2017-03-25T20:41:16 INFO src/common.c: Flash written and verified! jolly good!

How you should be able to see the STM32F4 Discovery board:

And here a small program which reads out the accelerometer LIS302DL and the most upper LED will be lit up. Be aware that on newer F4 Discovery boards this model has changed to LIS3DSH, which is not compatibel.

function onInit() {
 SPI1.setup({sck: A5, miso:A6, mosi:A7});
 SPI1.send([0x20,0b01000111], E3);
}

var avrx=0.0, avry=0.0;
function getAcc() {
  var accx = SPI1.send([0xA9,0], E3)[1];
  var accy = SPI1.send([0xAB,0], E3)[1];
  if (accx>127) accx-=256;
  if (accy>127) accy-=256;
  avrx = 0.1*accx + 0.9*avrx;
  avry = 0.1*accy + 0.9*avry;
  digitalWrite(LED1, avrx > 32);
  digitalWrite(LED4, avrx < -32);
  digitalWrite(LED2, avry > 32);
  digitalWrite(LED3, avry < -32);
}
onInit();setInterval(getAcc, 10);

Mar 202017
 

Bluetooth and its LE variant are new areas for me and, but the learning curve is not too steep thanks to Puck.js. Making  it do what I want is not easy though since I don’t know what it can do.

The most important documents are:

Here an example:

// Have a service to show temperature and battery level
// This is only visible when you are connecting to the Puck

var currentTemperature=E.getTemperature().toFixed(2)*100;

console.log("Temp: "+currentTemperature);

NRF.setServices({
 0x1809 : { // Health Thermometer
  0x2A6E: { // Temperature
   readable: true,
   notify: true,
   value : [ currentTemperature % 256, currentTemperature / 256 ]
  }
 },
 0x180f : { // Battery Level
  0x2a19 : { // Percentage
   readable : true,
   notify: true,
   value: [ Puck.getBatteryPercentage() ],
  }
 }
});

// Updating the temperature

setInterval(function() {
 currentTemperature += 1; // For debugging: increase temp by 0.01 degree per update
 NRF.updateServices({
  0x1809 : {
   0x2A6E : {
    value : [ currentTemperature % 256, currentTemperature / 256 ],
    notify: true
   }
  }
 });
}, 2000);

Mar 112017
 

My Espruino has colored I/O pins and since I saw this, I thought “That’s neat!”

Playing with the Orange Pi Zero and its 26 pin expansion port made me really want those colored pins as connecting things wrong can destroy ports quickly: 5V and 3.3V mixed up? Magic smoke escapes. Connected GND instead of I/O pin? 50% chance of a dead output port. Miss-counted pins and used pin 11 instead of 13…happy debugging!

The Asus Tinkerboard has it too:

but it seems this is not available without the rest of the Tinkerboard.

I had to build one from coloured 40 pin single row pins I got from AliExpress:

And here is the result:

Red is +5V, yellow is +3.3V, black is GND, blue is I²C and green is SPI. I don use UARTs a lot, so I did not bother to colour those.

Took about 15min of work incl. soldering. Totally worth it.

Mar 052017
 
Espruino, ESP8266 and the I2C OLED

Small Sunday afternoon project: Make the ESP8266 with Espruino work with the OLED display I have. NodeMCU has no issues. Time to try Espruino+JavaScript instead of NodeMCU+Lua.

Ingredients:

~/.local/bin/esptool.py --port /dev/ttyUSB0 --baud 115200 write_flash 
--flash_freq 80m --flash_mode qio --flash_size 32m \
 0x0000 "boot_v1.6.bin" \
0x1000 espruino_esp8266_user1.bin \
0x3FC000 esp_init_data_default.bin \
0x37E000 blank.bin
  • and then this little program will use it (if you have configured everything correctly and I2C works as it should):
I2C1.setup({sda: NodeMCU.D2, scl: NodeMCU.D1});

function start(){
 // write some text
 g.drawString("Hello World!",2,2);
 // write to the screen
 g.flip(); 
}

var g = require("SSD1306").connect(I2C1, start, {height:64});

 

Took me some tries to get it working and very helpful was the ability to scan the I2C bus:

function isDeviceOnBus(i2c,id) {
  try {
    return i2c.readFrom(id,1);
  }
  catch(err) {
    return -1;
  }
}

function detect(i2c,first, last) {
  first = first | 0;
  last = last | 0x77;
  var idsOnBus = Array();
  for (var id = first; id <= last; id++) {
    if ( isDeviceOnBus(i2c,id) != -1) {
      idsOnBus.push("0x"+id.toString(16));
    }
  }
  return idsOnBus;
}

I2C1.setup({sda: NodeMCU.D2, scl: NodeMCU.D1});
console.log('I2C detect as array:',detect(I2C1));

Note that I could not make the Wemos OLED work as its size (64×48) seems not supported. The 128×64 display I have worked out of the box. 128×32 is supposed to work too (see here).

 

Dec 182016
 
Orange Pi Zero - I/O

I finally figured out how to do simple I/O on the GPIO pins on the Orange Pi Zero. It’s actually the same as Raspberry Pi and it relies on /sys/class/gpio/

Most important: Use Armbian, and I in particular use 3.4.113 (legacy).

GPIO

 

Linux GPIO SOC Label CON4 CON4 Label SOC Linux GPIO
Vcc3V3-EXT 1 2 DCIN-5V
12 PA12 TWI0-SDA 3 4 DCIN-5V
11 PA11 TWI0-SCK 5 6 GND
6 PA6 PWM1 7 8 UART1_TX PG6 198
GND 9 10 UART1_RX PG7 199
1 PA1 UART2_RX 11 12 PA7 PA7 7
0 PA0 UART2_TX 13 14 GND
3 PA3 UART2_CTS 15 16 TWI1-SDA PA19  19
VCC3V3-EXT 17 18 TWI1-SCK PA18 18
15 PA15 SPI1_MOSI 19 20 GND
16 PA16 SPI1_MISO 21 22 UART2_RTS PA2 2
14 PA14 SPI1_CLK 23 24 SPI1_CS PA13 13
GND 25 26 PA10 PA10?

Note: PA10 does not seem to work.

 

To enable one GPIO pin, do this as root:

echo 7 >/sys/class/gpio/export
chmod a+rw /sys/class/gpio/gpio7/*

Now in NodeJS you can do (as non-root):

var Gpio = require('onoff').Gpio, 
  led = new Gpio(7, 'out'); 
 
function blinkled7() { 
  var state=false; 
  return function () { 
    console.log(state); 
    if (state) led.writeSync(0) 
    else led.writeSync(1); 
    state = ! state; 
    } 
} 
 
f=blinkled7(); 
setInterval(f, 1000);

which blinks GPIO pin 7 (AKA PA7). You can also watch pins:

var Gpio = require('onoff').Gpio,
  led = new Gpio(7, 'out'),
  button = new Gpio(16, 'in', 'both');

button.watch(function (err, value) {
  if (err) {
    throw err;
  }
  console.log("Changing to ", value);
  led.writeSync(value);
});

process.on('SIGINT', function () {
  console.log("Leaving...");
  led.unexport();
  button.unexport();
});

which makes the LED match what PA16 is. If you connect PA16 to e.g. PA6, you can change PA6, which is detected by PA16 which is reflected in the LED change on PA7!

 

LED’s

The 2 on-board LED’s can be controlled via

echo [0|1] > /sys/class/leds/[red|green]_led/brightness

which map to PA17 (red) and PL10 (green), but those are (of course) claimed by the LED driver.

PWM

Not figured out yet.

 

Dec 032016
 

Since I keep forgetting what pins I used for the ‘595 ICs which drive my 16 segment LED clock, here the pinout:

1: Vcc   2: GND
3: /SCK  4: NC
5: SER   6: NC
7: /RCK  8: NC
9:      10: NC

Since it’s HC595, Vcc is 2 up to 6V

And while on this topic, the 16 segment has this order when sending a 16 bit stream:

t-s-r-n-m-k-p-u-h-g-e-f-d-c-b-a.

Bit 0 is t, bit 15 is a.

Nov 192016
 
Orange Pi Zero - Neat

Got myself a (actually two) Orange Pi Zero: US$7, quad core ARM Cortex A7@1.2GHz, 256MB RAM, WLAN, FastEthernet, 1 USB, USB-to-go for power. All in a (about) 5×5 cm² package. Add in a 8GB microSD card, and it’s a small capable little board.

While the memory looks on the small side, itś plenty to run one program. Armbian uses about 40MB itself when running:

harald@opz1:~$ free 
              total        used        free      shared  buff/cache   available 
Mem:         247012       36720      142740        2168       67552      193175 
Swap:        131068           0      131068

leaving >200MB left. Given that I can have a (small, limited) web server runnig on an ESP8266 with about 40KB RAM, 256MB is plenty for a single-purpose server/controller.

Ethernet works (as expected). WLAN works via simple nmtui command.

Controlling the 2 LED’s is easy too:

root@opz1:/# cd /sys/class/leds/red_led 
root@opz1:/sys/class/leds/red_led# ls 
brightness  device  max_brightness  power  subsystem  trigger  uevent 
root@opz1:/sys/class/leds/red_led# echo 1 >brightness  

That turns on the red LED. Similar for the green LED.

To find out what GPIO’s exist, use this:

root@opz1:/sys/class/leds/red_led# cat /sys/kernel/debug/gpio                                              
GPIOs 0-383, platform/sunxi-pinctrl, sunxi-pinctrl: 
 gpio-10  (?                   ) out hi 
 gpio-17  (red_led             ) out hi 
 gpio-202 (xradio_irq          ) in  lo 
 gpio-354 (?                   ) out hi 
 gpio-362 (green_led           ) out hi

To export a GPIO, do

# echo 15 >/sys/class/gpio/export

and then in /sys/class/gpio/gpio15/ you can see the standard Linux kernel GPIO things like direction (in/out) and value (0/1)

See also the schematics which show what port of the H2+ connects to what thing: orange-pi-zero-schanetics-v1_11 (sp!)

 

Oct 302016
 

Previously I made LEDs on/off via Lua. The pin-order was 4, 3, 2, 1, 5, 0, 6, 7, 8 in NodeMCU: 6 red LEDs, and a RGB LED.

Using Espruino (specifically version 1.87), the order turns out to be: D2, D0, D4, D5, D14, D16?, D12, D13, D15. D1 seems to turn the WiFi LED on/off, which is a bit odd.

 

Update:

Espruino has a nice feature to convert NodeMCU pins into Espruino pins:

for (var i=1; i<11; ++i) { console.log(NodeMCU["D"+i])}
D5
D4
D0
D2
D14
D12
D13
D15
D3
D1

Or easier, just use NodeMCU.D1 for what was D1 in NodeMCU. It also helps to know that the Espruino numbers are simply the GPIO numbers of the ESP8266 (Espruino D5 = ESP8266 GPIO 14 = NodeMCU D1)

Oct 302016
 

Lua is neat, but learning Lua and JavaScript and NodeJS. Although Lua and especially NodeMCU is similar (not only in name) to NodeJS, it would be nicer to use only one language.

Here the recipe:

  1. Download espruino_1v87.tve_master_b3dc05b_esp8266.tgz
  2. Write flash (note: might use 80m and qio, but my old one does dio):
    ./esptool.py --port /dev/ttyUSB0 --baud 115200 write_flash --flash_freq 40m --flash_mode dio --flash_size 32m \
    0x0000 ~/Downloads/espruino_1v87.tve_master_b3dc05b_esp8266/boot_v1.6.bin \
    0x1000 ~/Downloads/espruino_1v87.tve_master_b3dc05b_esp8266/espruino_esp8266_user1.bin \
    0x3FC000 ~/Downloads/espruino_1v87.tve_master_b3dc05b_esp8266/esp_init_data_default.bin \
    0x37E000 ~/Downloads/espruino_1v87.tve_master_b3dc05b_esp8266/blank.bin
  3. Verify it:
    ./esptool.py --port /dev/ttyUSB0 --baud 115200 verify_flash \
    0x1000 ~/Downloads/espruino_1v87.tve_master_b3dc05b_esp8266/espruino_esp8266_user1.bin \
    0x3FC000 ~/Downloads/espruino_1v87.tve_master_b3dc05b_esp8266/esp_init_data_default.bin \
    0x37E000 ~/Downloads/espruino_1v87.tve_master_b3dc05b_esp8266/blank.bin
  4. Connect at 115200bps.
  5. Connect to your AP:
    var wifi = require("Wifi");
    wifi.connect("your_sid", {password:"your_password"}, function(err){
     console.log("connected? err=", err, "info=", wifi.getIP());
    });
    wifi.stopAP();
    wifi.save();
  6. In the Espruino IDE add the IP address
  7. When you reconnect via Espruino IDE, you should now have 2 choices: serial or TCP/IP via WLAN