More type in goodness…Half-Byte Tiny Basic type in game, Zapp the Moon Man, take 2

zappthemoonmanRelease three of Half-Byte Tiny Basic ate up about eight more bytes of memory than the previous release, so there are now 938 bytes free for user code to reside.  My last version of Zapp the Moon Man—previously unpublished—featured the Moon man’s ability to move down the screen and attack as well as the user’s ability to move the cannon back and forth.  Sadly, for this release, I’ve had to remove the downward mobility of the Moon Man, but I have left in the user’s ability to move and also made the ‘hit box’ better, resulting in a somewhat easier game play.

This game shows off just how versatile Tiny Basic can be, how speedy the ATMega 328 is and how quickly Tiny Basic can interpret your code.

At any one time in the game, both your cannon and the Moon Man can be moving as well as the torpedo you are shooting at the moon man.  Three objects to track on the screen. In interpreted BASIC. Running on a microcontroller that was meant for turning relays on and off, not playing video games. And, it does it rather smoothly.  The jerkiness that is there is there by design, to mimmick those games from the 1970’s.

The game is pretty primitive. It resembles Space Invaders, but there is only one ‘invader’, the Moon Man, and there are no protective shields…heck, the Moon Man does not even shoot at you…yet.  It does feature some primitive, character based, animated graphics.  The Moon Man sort of looks like a Space Invader. As it moves back and forth, its antennae move and its ‘feet’ swivel side to side.  You use a Wii Nunchuck’s thumb stick to move and the Z button to fire your torpedo. The game keeps a score…10 points for every Moon Man you destroy.  You hear a launch tone when you fire and, when you hit a Moon Man, you see a little explosion like effect. And…that’s it.  Simple and not earth shattering (that will be in a future update.)

So, with out any further delay…(One note: when typing in the code, do not put in extra spaces.  Use one space between the line number and the code, and one space before line numbers in things like GOTO or GOSUB.  The listing below inserted additional spacing, you can ignore it.)

100 CLS:ECHO 0
110 A=0:B=0:O=75
120 X=10:Y=10:Z=5:F=0:D=1:S=0
140 LINE 0,48,80,48,1
150 GOSUB 700
160 GOSUB 900
170 P=PAD(3):Q=PAD(0)
180 IF P=1 F=1:TONE 200,100
190 IF F=1 GOSUB 1000
192 IF Q>200 GOSUB 600
194 IF Q<100 GOSUB 600
200 A=A+D
210 IF A>15 D=-1
220 IF A<3 D=1
230 GOSUB 1200
290 GOTO 140
600 CURSOR X,Y:?”  “;
610 IF Q>200 I=1
620 IF Q<200 I=-1
630 X=X+I
640 IF X<2 X=2
650 IF X>17 X=17
660 GOSUB 900
690 RETURN
700 IF D=1 CURSOR A,B:?CHR(152);:DELAY O:CURSOR A,B:?CHR(153);:DELAY O:CURSOR A,B:?”  “;
710 IF D=-1 CURSOR A,B:?CHR(153);:DELAY O:CURSOR A,B:?CHR(152);:DELAY O:CURSOR A,B:?”  “;
790 RETURN
900 CURSOR X,Y:?CHR(150);
990 RETURN
1000 CURSOR X,Z:?”|”;:DELAY 20:CURSOR X,Z:?” “;:DELAY 20
1050 Z=Z-1
1060 IF Z=0 IF A=X Z=5: GOTO 1100
1070 IF Z=0 IF A=X+1 Z=5: GOTO 1100
1080 IF Z=0 Z=5:F=0
1090 RETURN
1100 CURSOR A,B
1110 ?”***”;:DELAY 180:CURSOR A,B:?”XXX”;:DELAY 170:CURSOR A,B:?”   “;:A=0:B=0:F=0
1190 S=S+10
1200 CURSOR 0,5:?”SCORE:”,S;
1290 RETURN

 

If you come up with any improvements, optimization, etc., please let us know.

Oh, one big caveat…as it does use up all but 15 bytes of RAM, your keyboard buffer is limited to 15 bytes…Tiny Basic does not set aside a dedicate memory for keyboard input. It dwindles as you use up memory.  So, keep in mind that you may have to delete a long line and split it up—which will use at least three bytes plus the content of the line.

UPDATE:  Since this was posted, I have made a few improvements to the game AND saved even more RAM, about 90 bytes total.  Among the improvements: a random speed for the moon man, the ability of the moon man to descend on you and…you can lose the game.

The updated code is below.

100 CLS
110 A=0:B=0:O=RND(100)
120 X=10:Y=8:Z=5:F=0:D=1:S=0
140 LINE 0,48,80,48,1
150 GOSUB 700
160 GOSUB 900
170 P=PAD(3):Q=PAD(0)
180 IF P=1 F=1:TONE 200,100
190 IF F=1 GOSUB 1000
192 IF Q>200 I=1:GOSUB 600
194 IF Q<100 I=-1:GOSUB 600
200 A=A+D
210 IF A>16 D=-1:B=B+1:if b>=Y CLS:?”You lose!”:Delay 3000:goto 100
220 IF A<1 D=1
230 GOSUB 1200
290 GOTO 140
600 CURSOR X,Y:?”  “;:X=X+I
640 IF X<2 X=2
650 IF X>17 X=17
660 GOSUB 900
690 RETURN
700 CURSOR A,B:?CHR(152);:DELAY O:CURSOR A,B:?CHR(153);:DELAY O:CURSOR A,B:?”  “;
790 RETURN
900 CURSOR X,Y:?CHR(150);
990 RETURN
1000 CURSOR X,Z:?”|”;:DELAY 20:CURSOR X,Z:?” “;:DELAY 20
1010 Z=Z-1
1060 IF X=A IF Z=B GOTO 1100
1070 IF X=A+1 IF Z=B GOTO 1100
1080 IF Z=0 Z=5:F=0
1090 RETURN
1100 CURSOR A,B
1110 ?”***”;:DELAY 180:CURSOR A,B:?”XXX”;:DELAY 170:CURSOR A,B:?”   “;:A=0:B=0:F=0
1120 Z=5
1190 S=S+10:O=RND(100)
1200 CURSOR 0,5:?”SCORE:”,S;
1290 RETURN

More type in goodness…Half-Byte Tiny Basic type in game, Zapp the Moon Man, take 2

zappthemoonmanRelease three of Half-Byte Tiny Basic ate up about eight more bytes of memory than the previous release, so there are now 938 bytes free for user code to reside.  My last version of Zapp the Moon Man—previously unpublished—featured the Moon man’s ability to move down the screen and attack as well as the user’s ability to move the cannon back and forth.  Sadly, for this release, I’ve had to remove the downward mobility of the Moon Man, but I have left in the user’s ability to move and also made the ‘hit box’ better, resulting in a somewhat easier game play.

This game shows off just how versatile Tiny Basic can be, how speedy the ATMega 328 is and how quickly Tiny Basic can interpret your code.

At any one time in the game, both your cannon and the Moon Man can be moving as well as the torpedo you are shooting at the moon man.  Three objects to track on the screen. In interpreted BASIC. Running on a microcontroller that was meant for turning relays on and off, not playing video games. And, it does it rather smoothly.  The jerkiness that is there is there by design, to mimmick those games from the 1970’s.

The game is pretty primitive. It resembles Space Invaders, but there is only one ‘invader’, the Moon Man, and there are no protective shields…heck, the Moon Man does not even shoot at you…yet.  It does feature some primitive, character based, animated graphics.  The Moon Man sort of looks like a Space Invader. As it moves back and forth, its antennae move and its ‘feet’ swivel side to side.  You use a Wii Nunchuck’s thumb stick to move and the Z button to fire your torpedo. The game keeps a score…10 points for every Moon Man you destroy.  You hear a launch tone when you fire and, when you hit a Moon Man, you see a little explosion like effect. And…that’s it.  Simple and not earth shattering (that will be in a future update.)

So, with out any further delay…(One note: when typing in the code, do not put in extra spaces.  Use one space between the line number and the code, and one space before line numbers in things like GOTO or GOSUB.  The listing below inserted additional spacing, you can ignore it.)

100 CLS:ECHO 0
110 A=0:B=0:O=75
120 X=10:Y=10:Z=5:F=0:D=1:S=0
140 LINE 0,48,80,48,1
150 GOSUB 700
160 GOSUB 900
170 P=PAD(3):Q=PAD(0)
180 IF P=1 F=1:TONE 200,100
190 IF F=1 GOSUB 1000
192 IF Q>200 GOSUB 600
194 IF Q<100 GOSUB 600
200 A=A+D
210 IF A>15 D=-1
220 IF A<3 D=1
230 GOSUB 1200
290 GOTO 140
600 CURSOR X,Y:?”  “;
610 IF Q>200 I=1
620 IF Q<200 I=-1
630 X=X+I
640 IF X<2 X=2
650 IF X>17 X=17
660 GOSUB 900
690 RETURN
700 IF D=1 CURSOR A,B:?CHR(152);:DELAY O:CURSOR A,B:?CHR(153);:DELAY O:CURSOR A,B:?”  “;
710 IF D=-1 CURSOR A,B:?CHR(153);:DELAY O:CURSOR A,B:?CHR(152);:DELAY O:CURSOR A,B:?”  “;
790 RETURN
900 CURSOR X,Y:?CHR(150);
990 RETURN
1000 CURSOR X,Z:?”|”;:DELAY 20:CURSOR X,Z:?” “;:DELAY 20
1050 Z=Z-1
1060 IF Z=0 IF A=X Z=5: GOTO 1100
1070 IF Z=0 IF A=X+1 Z=5: GOTO 1100
1080 IF Z=0 Z=5:F=0
1090 RETURN
1100 CURSOR A,B
1110 ?”***”;:DELAY 180:CURSOR A,B:?”XXX”;:DELAY 170:CURSOR A,B:?”   “;:A=0:B=0:F=0
1190 S=S+10
1200 CURSOR 0,5:?”SCORE:”,S;
1290 RETURN

 

If you come up with any improvements, optimization, etc., please let us know.

Oh, one big caveat…as it does use up all but 15 bytes of RAM, your keyboard buffer is limited to 15 bytes…Tiny Basic does not set aside a dedicate memory for keyboard input. It dwindles as you use up memory.  So, keep in mind that you may have to delete a long line and split it up—which will use at least three bytes plus the content of the line.

Giving your Arduino projects ‘sight’ and ‘touch’: using IR, Photocells and Touch Sensors to your project

12419231_974683622601393_320731550894605287_oOK, so I am taking some liberty here with the terms sight and touch, but it got your attention, yes?

In this post, I am going to briefly share how to use three sensors: a ‘light detector’ or photocell, a touch sensitive ‘button’ and an IR receiver.

These three sensors all came from a company called ‘OSEPP’, but similar sensors can be had from other vendors as well.  I am going to write about these three specific sensors, but you should be able to adapt the information to what ever you have.  I will present code in both Tiny Basic and Arduino.

LIGHT SENSOR

• 3 pin outs: GRD (-) VCC (+) S ( Signal)

• Suitable supply voltage: +3 to 5Vdc
• Analog voltage output: 0 to 5 Vdc
• Detects ambient light density
• Works with CdsPhotoresistor
• Interface with microcontrollers and logic circuits • Analog sensors
• Uses PH 2.0 socket
• Special sensor with Arduino expansion boards

The light sensor is a cool photocell that is mounted on little breakout board, making it easier to use in a project. There are three pins: VCC, GND and Signal. Signal would connect to any of the Analog pins. When in use, it not only will let you know if it detects light, but also returns the intensity. The higher the value, the more light it detects. Reading it easy and you do not need any libraries. See the HalfByte Tiny Basic example below.

100 CLS
110 L=0: # PIN A0
120 P=13:# PIN 13 LED
130 A=AREAD(L)
140 IF A>299 DWRITE P, 0
150 IF A<300 DWRITE P, 1
160 CURSOR 0,0
170 ?”Intensity: “, A,” ”
180 DELAY 250
190 GOTO 130

What this little piece of code will do is turn on the LED if the light level drops below 300 and turns it off if it goes above 299. It also writes the level to the screen.

if you add a line, say 155, you can test for no light:
155 IF A=0 CLS: ?”NO LIGHT DETECTED”:DELAY 2000

Or, you can test for too much light:
155 IF A>=600 CLS:?”THE LIGHT IS TOO BRIGHT.”:DELAY 2000

There are many things you can do, for example, control a servo that turns an armature to open a food door to distribute dog food to a dish when the sun comes up.

You can use it to log when the sun comes, goes down. Use it control lighting, etc.

Here’s the Arduino sample:

/* OSEPP example of measured ambient light intensity from photocell .
depending on brightness, an LED brightness is changed.
more light = brighter LED. */

int photocellPin = A0;    // photocell sensor input
int ledPin = 11;      // select the pin for the LED
int photocellValue = 0;  // variable to store the value coming from the photocell val

void setup() {
Serial.begin(9600);

}

void loop() {
// read the value from the sensor:
photocellValue = analogRead(photocellPin); 
photocellValue = constrain(photocellValue, 200, 800); //adjust depending on environment.  
   
  // change brightness of LED depending on light intensity of photocell
  int ledbrightness = map(photocellValue, 200, 800, 0, 255);
 
  Serial.print(“incoming value from photocell sensor =”);
  Serial.println( photocellValue);
  analogWrite(ledPin, ledbrightness); 
  delay(100);       
}

TOUCH SENSOR

• 3 pin outs: G (GRD) V (VCC) S ( Signal)Basic wiring scheme for all three sensors.
• 3-5 V operating range
• 5 mA minimum current requirement.
• Capacitive touch detection

The touch sensor detects when you are touching the plate on the breakout board.  As long as you are touching the sensor, it returns a value.  You can test the value and determine if there is someone touching the sensor.

Arduino Code:

/*

OSEPP Touch Sensor Module Example

Serial monitor prints values output from touch sensor
when body conductivity applied.
*/

int sensorPin = A0;    // select the input pin for the potentiometer
int sensorValue = 0;  // variable to store the value coming from the sensor

void setup() {
  Serial.begin(9600);
  // declare the ledPin as an OUTPUT:
}

void loop() {
  // read the value from the sensor:
  sensorValue = analogRead(sensorPin);
  Serial.println(“Touch Sensor Value = ” + sensorValue);

}

Tiny Basic Code:

100 CLS
110 L=0: # PIN A0
120 P=13:# PIN 13 LED
130 A=AREAD(L)
140 IF A>100 DWRITE P, 0
150 IF A<100 DWRITE P, 1
160 CURSOR 0,0
170 ?”Value: “, A,” ”
180 DELAY 250
190 GOTO 130

The Tiny Basic, very similar to the light sensor code, will turn the LED on and off each time you press the sensor.  On my setup, the values switch between 22 and 1023.  Your mileage may vary.

IR Sensor12792206_974716205931468_7006422127672690003_o

• 100% Arduino Compatible
• 3 pin outs: G –Ground V – 5V S – Signal
• Operates at a frequency of 38khz

The IR Sensor allows control of a circuit via an Infra Red remote or other IR source.  It works very much like the other two sensors here: has a ground, voltage and signal pins.  It returns values based on the IR signal received.  Admittedly, I have not yet done much with the sensor, so I have limited experience with it.  You can use the same Tiny Basic example from the Touch Sensor above.

Arduino Code:

/*
infrared sensor reciver. connect signal of infrared to analog pin 0. as the distance
from an object to sensor increases/decreases, you will increase/decrease
speed of led blinks from HIGH to LOW

*/

int IR_Pin = A0;    // select the input pin for the potentiometer
int IR_Value = 0;  // variable to store the value coming from the sensor

void setup() {
  // declare the ledPin as an OUTPUT:
  Serial.begin(9600);
}

void loop() {
  // read the value from the sensor:
  IR_Value = analogRead(IR_Pin);   
 
Serial.println(“delay value for LED = “+ IR_Value);  //what value are we reading once an IR led is detected?

// IR_VALUE  = constrain(IR_VALUE, 0, 100); // optional to add a strict range
}

In each of the examples above, the sensors are connected to the HalfByte Console (or your Arduino compatible) via pin A0.  You can use what ever analog pins you want, just change the reference in the code.  You can use them together as well.

Building a WiFi based Room Monitor using an ESP8266 and an Arduino compatible

BeautifulPhoto635888272313367045Having purchased a few of the ESP8266 WiFi modules, I decided to devote one of them to a room monitoring device.  I live i a fairly good sized home, with an oversized garage. The room over the garage is a bedroom.  Well, the room, while nicely insulated, is huge and is difficult to maintain the same temperature as the rest of the upstairs.  And, since it is a bedroom where a child who has a problem maintaining his body temperature sleeps and plays, we need to keep an eye on the temp in that room.

I did have an Arduino UNO with the ethernet shield and a DHT11 sensor in the room, but the ethernet sheild did not work well with the WiFi extender I have in the room.  And, wanting to actually build something specifically for the purpose at hand, I decided to design and build a solution around the wifi module.

It needed to be simple and, preferably, run off of a battery.  While I have not yet gotten to WP_20160106_15_27_46_Pro_LIthe battery solution yet, I do have the rest built and am working on the code.

The whole thing fits on a 2.5 by 2inch perf board. It features an Atmega 328 chip, a Nokia 5110 LCD, DHT11 temp/humidity module, the aforementioned ESP8266 module, LED’s, a few caps and resistors and a 16mhz crystal.

WP_20160112_22_25_33_Pro_LIAssembly was easy.  Remembering the cathode on an LED…that’s hard, for me.  I always hated those damn things.  I love blinky lights, but can’t stand to wire up the things.  UGH.  Anyway, I’m only using a few of the I/O pins on the 328: Serial in and out, D2, A4, A5 and, for the LCD, D3 through D7.  This leaves a few pins for you to use if you wish to expand the capabilities of the device.

I started out by soldering the socket for the chip.  Then, I wired up the reset, which is pin 1 to a WP_20160119_22_28_27_Pro_LImomentary push button connected to ground.  I then wired up pin 13 to an LED via a 150 ohm resistor, connected to ground. Power (pin 7) and  ground (pin 8) were next.  You can test, at this point, by inserting a 328 that has the standard Arduino bootloader and nothing else burned into the chip. Insert the chip, apply five volts and the LED should blink.  If so, congrats!

You can install a power on LED as well.  Solder an LED and 150 ohm resistor to ground and Pin 7. When power is applied, the LED should light up.

The crystal was next.  Solder the crystal to pins 9 and 10.  Solder a 22pF capacitor to each each pin of the crystal and tie them to ground.

If you are at this point, congratulations, you have built a very basic Arduino compatible microcontroller. 

WP_20160115_18_50_02_Pro_LIFrom this point, I soldered some headers so I could connect serial I/O, power and the connections for the DHT11 and RTC (1307).   I then soldered the Nokia 5110 to the board and connected it as follows:

pin 7 – Serial clock out (SCLK)
pin 6 – Serial data out (DIN)
pin 5 – Data/Command select (D/C)
pin 4 – LCD chip select (CS)
pin 3 – LCD reset (RST)

Connect pin 6 on the LCD to +5, pin 8 to Ground and pin 7 to +5 if you want the back light. I connected a switch to my display so I could turn the light on or off.  Add the swtich between the +5 and pin 7 if you wish.

I uploaded a demo 5110 sketch to make sure the screen worked. It did.

The DHT only has one data pin, the middle pin, and it goes to D2 on the chip.  Connect the others to +5 and ground.

WP_20160118_00_04_44_Pro_LI (2)As the ESP8266 is intolerant of higher voltages, I installed a 3.3v regulator to power the module.  I grab a five volt line, solder it to the right pin of the to220 regulator, the left most pin to ground and the middle pin to the VCC pin on the 8266.  The TX line from the 8266 goes to D0 on the 328, the RX line to D1 and, ground to ground. You also, if you have the v1 of the module, connect power to the chip select pin (4) of the 8266 as well as connect its RST pin to the reset pin of the 328. 

The RTC (real time clock) is connected:
SCL to A5 on 328
SDA to A4 on 328
VCC to +5
GND to ground

Connect it all up and you have a complete wifi based room monitor. For now, it returns the temperature and humidity.  At somepoint, I am going to return a timestamp so I graph the data and figure out when the temperature spikes or cools. 

Software

WP_20160122_13_12_55_Pro_LIGetting the LCD to display the date, time, temperature and humidity was simple.  The issue I have is with the wifi module. And it is also keeping me from posting a complete solution. So, I am going to post what I have. If one of you can figure out the webserver piece, please share it with us. I am sure it is something I am doing wrong. 

The code is at the end of this post.

Building things from ‘scratch’ is far more rewarding than just connecting a few sensors to an UNO or some other board.  But, you can do that if you wish.  At any rate, no matter what you do, YOU are still doing it and that is what matters. 

Code:

/*********************************************************************
* This sketch uses the Adafruit libraries for Monochrome Nokia 5110 LCD Displays
*
* Pick one up today in the adafruit shop!
* ——> http://www.adafruit.com/products/338
*
* These displays use SPI to communicate, 4 or 5 pins are required to
* interface
*
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
* Written by Limor Fried/Ladyada  for Adafruit Industries.
* BSD license, check license.txt for more information
* All text above, and the splash screen must be included in any redistribution
*********************************************************************/

#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#include “DHT.h”
#include <Wire.h>
#include “RTClib.h”

#define BUFFER_SIZE 128
char buffer[BUFFER_SIZE];

DHT dht;
RTC_DS1307 rtc;

// pin 7 – Serial clock out (SCLK)
// pin 6 – Serial data out (DIN)
// pin 5 – Data/Command select (D/C)
// pin 4 – LCD chip select (CS)
// pin 3 – LCD reset (RST)
Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3);

// Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734
#ifdef PROGMEM
#undef PROGMEM
#define PROGMEM __attribute__((section(“.progmem.vars”)))
#endif
const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000001, B10000000,
  B00000011, B11000000,
  B00000111, B11100000,
  B00001111, B11110000,
  B00000000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000
};
#define SCREENWIDTH 84
#define SCREENHEIGHT 48

#define DEBUG true
const int ESP8266_CHPD = 4;
int isConnected = false;

void setup() {

  display.begin();
  Wire.begin();
  rtc.begin();
  //rtc.adjust(DateTime(__DATE__, __TIME__));
  if (! rtc.isrunning()) {
    display.println(“RTC is NOT running!”);
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(__DATE__, __TIME__));
  }
  Serial.begin(115200); // your esp’s baud rate might be different
  Serial.setTimeout(5000);
  Serial.println(“AT+RST”);

  if (Serial.find(“ready”))
  {
    display.println(“Module is ready”);
    isConnected = true;
    display.drawBitmap(0, 0, logo16_glcd_bmp, 16, 16, BLACK);
    display.display();
  }
  else
  {
    display.println(“Module have no response.”);
    display.display();
    setup();
  }
  Serial.print(“AT+CWMODE=1\r\n”);
  Serial.print(“AT+CWJAP=\”xxx\”,\”xxx\”\r\n”);  //replace xxx with your ssid and password
  Serial.print(“AT+CIFSR\r\n”);
  Serial.print(“AT+CIPMUX=1\r\n”);
  Serial.print(“AT+CIPSERVER=1,80\r\n”);
  display.println(Serial.read());
  display.setContrast(50);
  dht.setup(2); // data pin 2
  display.display(); // show splashscreen
  delay(2000);
  display.clearDisplay();   // clears the screen and buffer
  display.display();
  display.setTextSize(1);
  display.setTextColor(BLACK);
  display.println(“HalfByte Room    Monitor”);

  display.display();
  delay(3000);
  display.clearDisplay();
  display.setTextSize(1);
}

void loop() {
  int ch_id, packet_len;
  char *pb;
  Serial.readBytesUntil(‘\n’, buffer, BUFFER_SIZE);

  delay(dht.getMinimumSamplingPeriod());

  float humidity = dht.getHumidity();
  float temperature = dht.getTemperature();

  display.clearDisplay();
  display.display();
  if (isConnected == true) {
    display.drawBitmap(70, 0, logo16_glcd_bmp, 16, 16, BLACK);
    display.display();
  }
  display.setCursor(3, 29);
  display.print(“Humidity: “);
  display.setCursor(display.width() / 2, 38);
  display.print(humidity, 1);
  display.print(“%”);
  display.setCursor(3, 20);
  display.print(“Temp: “);
  display.setCursor(40, 20);
  display.print(dht.toFahrenheit(temperature), 1);
  display.print(“F”);
  display.drawRect(0, 28, display.width(), 19, BLACK);
  display.display();

  DateTime now = rtc.now();
  display.setCursor((display.width() / 2) – 35, 1);
  if (now.month() < 10) display.print(0);
  display.print(now.month(), DEC);
  display.print(‘/’);
  if (now.day() < 10) display.print(0);
  display.print(now.day(), DEC);
  display.print(‘/’);
  display.print(now.year(), DEC);
  display.setCursor((display.width() / 2) – 30, 12);
  if (now.hour() < 10) display.print(0);
  display.print(now.hour(), DEC);
  display.print(‘:’);
  if (now.minute() < 10) display.print(0);
  display.print(now.minute(), DEC);
  display.print(‘:’);
  if (now.second() < 10) display.print(0);
  display.print(now.second(), DEC);
  display.display();

  if (strncmp(buffer, “+IPD,”, 5) == 0) {
    // request: +IPD,ch,len:data
    sscanf(buffer + 5, “%d,%d”, &ch_id, &packet_len);
    if (packet_len > 0) {
      // read serial until packet_len character received
      // start from :
      pb = buffer + 5;
      while (*pb != ‘:’) pb++;
      pb++;
      if (strncmp(pb, “GET / “, 6) == 0)
        //if (Serial.available()) // check if the esp is sending a message
        //{
        if (Serial.find(“+IPD,”))
        {
          //delay(1000);
          delay(100);
          clearSerialBuffer();
          int connectionId = Serial.read() – 48; // subtract 48 because the read() function returns
          display.print(connectionId);
          display.display();
          // the ASCII decimal value and 0 (the first decimal number) starts at 48
          homepage(connectionId);
        }
    }
  }
}

void homepage(int ch_id) {
  String Header;
  float temperature = dht.getTemperature();
  Header =  “HTTP/1.1 200 OK\r\n”;
  Header += “Content-Type: text/html\r\n”;
  Header += “Connection: close\r\n”;
  Header += “Refresh: 5\r\n”;

  String Content;
  Content = “Environmental Status:<br/>”;
  Content += String(“<B>Temperature:</b>”);
  Content += String(dht.toFahrenheit(temperature));
  Content += String(“<br><b>Humidity: </b>”);
  Content += String(dht.getHumidity());
  Header += “Content-Length: “;
  Header += (int)(Content.length());
  Header += “\r\n\r\n”;

  Serial.print(“AT+CIPSEND=”);
  Serial.print(ch_id);
  Serial.print(“,”);
  Serial.println(Header.length() + Content.length());
  delay(10);

  //if (Serial.find(“>”))
  {
    Serial.print(Header);
    Serial.print(Content);
    Serial.println(“AT+CIPCLOSE=0”);

    delay(10);
  }
}

// Get the data from the WiFi module and send it to the debug serial port
String GetResponse(String AT_Command, int wait) {
  String tmpData;

  Serial.println(AT_Command);
  delay(10);
  while (Serial.available() > 0 )  {
    char c = Serial.read();
    tmpData += c;

    if ( tmpData.indexOf(AT_Command) > -1 )
      tmpData = “”;
    else
      tmpData.trim();

  }
  return tmpData;
}

void clearSerialBuffer(void) {
  while ( Serial.available() > 0 ) {
    Serial.read();
  }
}

void clearBuffer(void) {
  for (int i = 0; i < BUFFER_SIZE; i++ ) {
    buffer[i] = 0;
  }
}

boolean connectWiFi(String NetworkSSID, String NetworkPASS) {
  String cmd = “AT+CWJAP=\””;
  cmd += NetworkSSID;
  cmd += “\”,\””;
  cmd += NetworkPASS;
  cmd += “\””;

  GetResponse(cmd, 10);
}

The ESP8266 WiFi Module–how to get it to work with an Arduino

WP_20160106_15_27_46_Pro_LIFinally got around to playing with the ESP8266 WiFi Module with an Arduino UNO.  I am using the UNO simply because it has a steady, 3.3v output while the HalfByte Console isn’t as steady and the module is, from everything I have read, is not tolerant of much more than the 3.3 volts.  Until I fix the console’s 3.3volt output, I will use the UNO.

Before I go on, I have to say, this little board isn’t very reliable. It is only connecting about a third of the time.

The documentation is spotty, even though it has been out for quite sometime now.  So, I hope to help anyone who just wants to use it as a WiFi module and not reprogram it to play Tic Tac Toe.

First, it is important to know which module you have as there are quite a few variations.  You go here to figure that out. The board I have is an ESP-01 Rev 2.  The Rev is important as you have a couple of extra steps from the rev 1 board.

From the wiki, here’s the pin out for the rev 2 board:

image

In order for this thing to work, you MUST jumper the CHIP_EN (or CHIP_PD) pin to the VCC pin, pulling the pin high.  This enables the whole thing to, you know, work. 

One other important detail…the baud rate is 115,200.  Most documentation I read said it was 9600, but, at least on mine, it is 115,200 baud.

Those two things were the key for me to get my module to connect and work.

Wiring it up is easy:image

ESP8266 ARDUINO
UTX RX (pin 0)
URX TX (pin 1)
GND GND
VCC 3.3V
CHIP_EN 3.3V
RST Reset

The code is straightforward enough. I copied an example from the wiki and modified it to work with my module and took out some extraneous junk.WP_20160106_15_59_14_Pro_LI (2)

Code:

#include <SoftwareSerial.h>
#define SSID        “xxx”
#define PASS        “xxx”
#define DST_IP      “173.194.116.116”    //google.com
SoftwareSerial dbgSerial(10, 11); // RX, TX
void setup() 
{
    // Open serial communications and wait for port to open:
    Serial.begin(115200);
    Serial.setTimeout(5000);
    dbgSerial.begin(9600);  //can’t be faster than 19200 for softserial
    dbgSerial.println(“ESP8266 Demo”);
    //test if the module is ready
    Serial.println(“AT+RST”);
    delay(1000);
    if(Serial.find(“ready”))
    {
        dbgSerial.println(“Module is ready”);
     }
    else
    {
        dbgSerial.println(“Module have no response.”);
        while(1);
     }
    delay(1000);
    //connect to the wifi
    boolean connected=false;
    for(int i=0;i<5;i++)
    {
    if(connectWiFi())
      {
      connected = true;
      break;
      }
    }
    if (!connected){while(1);}
      delay(5000);
      //set the single connection mode
      Serial.println(“AT+CIPMUX=0”);
}
void loop()
{
  String cmd = “AT+CIPSTART=\”TCP\”,\””;
  cmd += DST_IP;
  cmd += “\”,80″;
  Serial.println(cmd);
  dbgSerial.println(cmd);
  if(Serial.find(“Error”)) return;
  cmd = “GET / HTTP/1.0\r\n\r\n”;
  Serial.print(“AT+CIPSEND=”);
  Serial.println(cmd.length());
  if(Serial.find(“>”))
  {
    dbgSerial.print(“>”);
  }else
  {
    Serial.println(“AT+CIPCLOSE”);
    dbgSerial.println(“connect timeout”);
    delay(1000);
    return;
  }
  Serial.print(cmd);
  delay(2000);
  //Serial.find(“+IPD”);
  while (Serial.available())
  {
  char c = Serial.read();
  dbgSerial.write(c);
  if(c==’\r’) dbgSerial.print(‘\n’);
  }
  dbgSerial.println(“====”);
  delay(1000);
}
boolean connectWiFi()
{
  Serial.println(“AT+CWMODE=1”);
  String cmd=”AT+CWJAP=\””;
  cmd+=SSID;
  cmd+=”\”,\””;
  cmd+=PASS;
  cmd+=”\””;
  dbgSerial.println(cmd);
  Serial.println(cmd);
  delay(2000);
  if(Serial.find(“OK”))
  {
    dbgSerial.println(“OK, Connected to WiFi.”);
    return true;
  }else
  {
    dbgSerial.println(“Can not connect to the WiFi.”);
    return false;
  }
}

Because I am using the serial I/O on the UNO for the module, I used softwareserial to talk to a HalfByte Console running the HalfByte graphical terminal sketch so I could see the output of the module.  Normally, you would, likely, not have any kind of output on the Arduino as you’d be using the WiFi module for your I/O. I’m guessing.

I may order a few more of these things to play with reprogramming them and running code directly on them.  There is a Basic Language interpreter, LUA and Javascript for them, so I may play with that.  For now, IF I can get it working reliably, I may pair one with an ATTINY85, like a Trinket or DigiSpark, and a DHT11 temp sensor and set up a network of wireless thermometers in the house. 

I can see the potential, but the reliability is an issue.

Waduzitdo: a simple language anyone can learn, part 1

Back in the late 1970’s, having a home computer was unique, not many people had one.  And, when those who did have one had family or friends over, the question that was asked was ‘Well, what does it do?’ Unfortunately, back then, they didn’t do a whole lot unless you knew how to write code.  That usually meant either some flavor of Basic or you had to learn assembler or ‘machine code’.  I did quite a bit of ‘machine code’ as I could not afford a full blown assembler.  Anyway, someone got tired of answering the question and whipped up a little language called ‘Waduzitdo’.  This little language was small, had few statements and was easily learned. 

Waduzitdo had little structure, statements were in the form of:

statement: value or text

There were seven statements:

Statement Parameter Meaning
T text Type <text> on the console
A variable Ask a question, put answer in <variable>
M<variable> text Match <variable> with <text> result goes on stack
JY jump number Jump if stack is true to line number
JN jump number Jump if stack is false to line number
J jump number Jump to line number
E none End

As you can see, it was REALLY simple. A sample ‘application’ would look like:

*T: Hello, this is Waduzitdo.
T: What is your name?
A: n
T: Hello,
Tn:
T: Do you want to see this again?
A: a
M: yes
JY:1
T: Good bye!

A few things, the asterisk is a line number.  Rather than using numbers, you used asterisks.  The first asterisk is ‘line 1’, second is ‘line 2’ and so on. As programs will be small, keeping track of them should not be an issue.  Variables can be on both sides of the colon, depending on the statement. For statements that have no parameters, like Accept, the variable is on the right. If the statement does have a parameter, the variable goes on the left. The Y and N goes before the colon. 

HalfByte’s implementation will include the core of the language and support for graphics, sound and limited math and the nunchuck.  The graphics will be similar to ‘turtle graphics’ of the 70’s and 80’s.  While I have not yet settled on a complete feature set, I do know that standard math, random numbers and limited string support will be there.  I will use some of the code from Tiny Basic but most of it will be new.  I am not going to use any of the source from the original language, but I am going to attempt to adhere to its style.

My goal is to document, via this blog, the process of writing this language for the Half-Byte Console (and other Arduino compatibles.)

So, stay tuned!  This should be fun.

The archive. Confetti. Type in programs. Read.

syncmagAs part of putting together a package of materials for Half-Byte Tiny Basic, I came across several gems that either reminded me of my early computing days or are cool enough for me to write about.

One such site is the Internet Archive. (The link takes you to the magazine rack. From there, use the search bar near the top of the page, and search for, say, ‘Byte’. Or computer magazines.)

Now, this site has a treasure trove of material, including the Way-Back machine. The Way-Back machine allows you to enter a URL and then see it in various incarnation through the years. It’s really interesting to see how the Internet and web design have developed. But, that’s not what caught my eye, as cool as that is.

No, it was the site’s collection of magazines, specifically, computer magazines. You can download scanned images of whole magazines, going back to the mid 1970’s.  I remember quite a few and even had many of them. At one point, I had the first ten years of Byte Magazine, THE computer magazine of the 1970’s and ‘80s.

Now, the magazines I was looking for, Dr Dobb’s (another one that I had the first seven years worth, but, no longer) Journal and a bunch of Sinclair ZX related magazines. Unfortunately, CMP has Dr Dobbs, so you won’t find it here, however, you will find Byte and a whole slew of Tandy, Commodore, Atari and, of course, Sinclair related magazines.

The quality of the scans various widely. Some are really nicely done and care taken to line them up correctly, etc. BUT…some were not cared for very well. But, hey, they ARE scanned and there’s no charge to download them, so…all considered, it is a treasure trove that I’ll not complain about.

So, I did find a few things that I was looking for, namely some type-in BASIC programs.  I am putting together a booklet of short type-in programs-games-to use on the Half-Byte Console and Tiny Basic. And, the Sinclair flavour of BASIC is close and the ZX-81 lunarzx81specs are very close to the Half-Byte Console, so the conversion is pretty easy. I will also be writing about such a conversion process. The downside is that there are few examples of Tiny Basic software, or other BASIC for that matter.  Type in software is a thing of the past and pre-dates the Internet. 

I certainly remember the thrill of getting my next issue of Computer Shopper, Compute! or Sync Magazine and anxiously looking at the type in games or utilities and converting them to whatever computer I wanted to use them on.  I had my ZX-81, my TRS-80 Color Computer and, eventually, a Xerox 820 that ran CP/M and several flavors of Basic. Of course, the 32k Extended Microsoft Basic was my favorite, but the Xerox had no graphics, so I spent a lot of time on the ZX or the CoCo. 

Typing in games was great. I got to learn what the program did, hone my typing skills and felt accomplished when I typed that last line, saved and then type RUN.  Inevitably, of course, I would have made a mistake and would have to fix it. Sometimes, I made no mistake-the listing was just wrong. Other times, I made a mistake converting the code and would have to correct it. Sometimes, that took minutes. Other times…DAYS. Oh my. I remember one game that took me hours to type in on my CoCo. I had an original CoCo, which had a crummy key board. UGH.  I hated that thing.  Never replaced it though.  Should have. 

Anyway, I get through typing in this game. Saved it on two different tapes, just to make sure. I type RUN, press RETURN and…nothing.  The damned computer hung.  I had to TURN IT OFF! Now, this meant re-loading the game and trying to figure out why it choked.  Loading anything from a tape was a laborious and risky task.  Will it load? You pray, even if you don’t believe, you pray that the Tape Gods are  favorable to you today and will allow the software to load.  Fortunately, I had not upset the Tape Gods and all was good.  I figured out that I had reversed two numbers that were in some MACHINE CODE that was getting POKED into memory and run.  So, I fix that.  Re-save. On three tapes, this time. I want to be safe.

I type RUN.

Boom! Confetti!

It started. 

I followed the directions and pressed the space bar to start the game.

Boom! No Jimmy Johnson. No Confetti. Only a damned Syntax Error and that stupid multi-colored cursor blink at me.

This problem, a multi-statement line where I left out a bloody colon in the middle of the line. That…took a week to find.  I ended up just retyping the line. Three times! I mistyped that same line two different times. The third time was the charm.  This time, there was confetti. And, it was good.

Ah, those were the days. ‘Free’ and open source software before it was called that. Well, not totally free. You still had to buy the magazine.

So, sit right back my friends, you are sure to get a smile…or a chuckle. Once the console is out of the door, expect to see a few type in games or utilities on these pages from time to time.