2009-12-30

Accidents happen... hoppefully only in 2009

I apparently only write about my bike(s) when something bad happens, well today I was ran over by a car...
I was comming from Pavillonengracht through the Stille Veerkade, night had just fallen, I was returning home after a small "shop tour" looking for agendas for 2010, a small computer mouse and a couple of pen refills.

View Larger Map
I had my lights on, as I remember turning them on when leaving the last shop. I had the priority and I saw the car waiting, I thought he saw me... Unfortunately he did not! The car hit me on the pedals, lost my balance and fell to the floor on my side and hit the head. I was amazed on how fast the general public reacted, immediately someone came to me, told me not to move and called emergency service. They started talking to me too fast for me to understand, I asked if they could speak in English and they all changed to English. They asked the usual questions, "if I had lost conscience?, pain in the neck?, if I thought I had anything broken?", "No,No,No" I said... the police arrived checked how I was, followed in a few minutes by the ambulance. By then I was pretty sure that I had nothing very serious, but I could have a broken rib.
In the ambulance a quick check was made, nothing broken just some bruises... Blood pressure and pulse a bit high (I think I was in shock), but nothing serious apparently.
Coming out of the ambulance, the police was waiting for ID check and note taking of the accident.
The man that hit me was also a bit nervous, I greeted him told him that I was OK, we exchanged addresses and contacts for the insurance and parted ways. I'll have the bike at the repair shop next week.
My sincere thanks to everyone that helped me, the casual people that called the police and came to help me, the Haaglanden politie and the Emergency Service in the ambulance.
The Kronan was not left in a good shape, she had taken most of the hit... we'll see how she'll recover from this one...



.... Update, after taking the bike to the incompetent bike shop under Den Haag Centraal Station, on the first ride I noticed the frame was bent... really bad... I'm not very hopeful that the bike can be repaired :-( ...

2009-12-19

SolarLight (3) - First Prototype


Well after the initial breadboard, I decided to do some extra work on the Solarlight. I built a perfboard/smd board prototype and as usual I had to do some "adjustments".
Since my ATTiny45U in DIP are "precious" I wanted to use instead one of my ATTiny15L that I had around (a previous buy in ebay).

There are some major differences between the Tiny45 and the Tiny15L:
- Software - the Tiny15L does not have RAM and has a fixed length stack (3), programming it using avr-gcc is difficult and involves "tweaking" the code (see more here). The Tiny15L also does not have the debugwire interface, so debugging is a bit more difficult. Therefore I decided to develop the code in AVRStudio in windows (bah!) in assembler, as much as I like linux the simulators available are still far from perfect. One final remark on the simulator in AVRStudio, always read the notes about your processor, in the case of the ATTiny15L the watchdog is not simulated and the noise reduction sleep/wake-up on ADC conversion complete is not simulated!!
- Hardware - the pins and ADC input PB3/PB4 are switched (mentioned here), the ADC converter internal reference is fixed to 2.56V (ATTiny45U has 2.56V and 1.1V), the ATTiny45U has more power saving options and the frequency of the maximum PLL frequency (important for a high speed converter) is higher on the Tiny45 (8x8MHz=64MHz) than on the Tiny15 (16x1.6MHz=25.6MHz), the CPU clock also higher on the Tiny45 (8MHz) against the Tiny15 (16MHz).

The light is working but there are still some software issues to solve. As I mentioned the ATtiny15L does not have the debugwire interface, in order to debug the project I decided to encode data in the status LED as a bit-banged serial port (like this one), when I want to see a value of a conversion or get a check point or value, I change the code and wait for it to show up on the scope.
I also decided that I had to have a way of forcing a full light mode and a half light mode (both independent of the battery and charging) in case I connected the light using an adaptor (no solar light mode). For this I thought of using this same status pin, curiously this pin is placed between VCC and GND in the programming connector, so a simple jumper could activate these modes in the final product.

2009-11-27

SolarLight (2) and gEDA simulation

An update over SolarLight, I finally managed to print waveforms from ngspice in OpenSuse 11.2 . For some reason the interface is not what you would expect and it has become much more complicated to print a waveform than before.
The first time I installed gEDA from the sources (under OpenSuse 10.3), now I'm using a precompiled version from the OpenSuse Science repository, it could be that the precompiled version has the printer interface "disabled" in some way.
Back to waveform printing, under ngspice one would follow the following path to simulate and plot a waveform:
tran 100n 1.5m
plot v(501),v1000#branch

In the case of the SEPIC circuit of a previous post this would run transient simulation until t=1.5ms with a minimum time step of 100ns (try not to have more than a few thousand simulation points), the second line would open a new window with the output voltage and LED current displayed.
Previously when I pressed in the hardcopy button the print interface would appear and I could chose the printer and/or print to file. Now a message appears in the console:
The file "/tmp/hc4803" may be printed with the Unix "plot" command,or by using the '-g' flag to the Unix lpr command.

If you try the "lpr -g" command either the system complains that it is not supported or that no printer is installed.
lpr: Warning - 'g' format modifier not supported - output may not be correct!
lpr: Error - no default destination available.

After installing plotutils I managed to convert the plotted file (hc4803) to almost any known format (for example postscript or png) with the command:
plot --output-format ps hc4803 > hc4803.ps
plot --output-format png hc4803 > hc4803.png

This allows the plots to be printed and included in documents or webpages, the plot looks something like this:

Then I wanted to try out gwave, gwave is a waveform viewer, part of the gEDA package but its use is far from trivial. First in gwave you must run a simulation and then write the data to a file:

tran 100ns 1.5ms
write plotdata.dta

then run gwave with this data.

gwave plotdata.dta

The interface is far from trivial, I was unable to use colours for the plot and I also had error while trying to print a plot, but at least I could see some waveforms. Results may vary depending on your installed system, but here is a screenshot of the program, the waveforms are in gray on black background:


I'm now temped in building the gEDA toolsuite from scratch... but for that I need some more time...

2009-11-22

SolarLight

Some time ago I had the idea of building a LED lamp that was solar powered, harvesting the Sun during the day and charging the battery, while at night deliver some light. The idea was to extend the hours of light of my peppers during the winter, once the vase was inside the house.

For the initial design I wanted to use two old Ni-Cd batteries and for this supply voltage I would need to use a low voltage oscillator circuit as the minimum voltage would be around 2.0V. The converter would be a boost converter since the Luxeon K2 I had were rated for minimum 2.79V. I started by using a general Boost converter design procedure, and then simulate the circuit in gEDA/SPICE/ngspice.


I stumbled in two problems:
- after some tries with simple transistor oscillator circuits, low voltage comparators, and PWM modulators I decided to use a micro-controller. The biggest problem was the low voltage, even the low voltage circuits shut-down at 3.0V. Then I decided to use a low-voltage micro like the ATTiny45U capable of operating from 1.8V.
-The booster wasn't working, the LED was conducting slightly when the oscillator was off, a known problem with boosters, if the load consumes power at the input voltage minus a diode drop the circuit is always draining the battery.

Finally I decided to redesign the circuit using a 3 element battery, this time a scrap battery from a mobilephone Li-Mh with 3.7V, this would ease the micro selection (Attiny15L that I used before) and I had to change the type of converter to a SEPIC, that allows the use of a battery with a voltage close to the LED conduction voltage. The circuit has the advantage of being capable of boosting or dropping the input voltage, this application note and this one are quite useful for the design phase. Since the load is an LED I allowed a bigger fluctuation in the inductor currents and of the output current, then I chose the operating frequency function of inductors I had available.

Again, after calculating the circuit components I drew a circuit in gEDA and simulated the circuit. As a general design procedure the circuit I use to simulate is very different from the one that I'll build in the breadboard/PCB.

I placed some components inside green boxes to simulate real inductors with series resistance and real capacitors with series resistance. The voltage sources with zero voltage in some branches allow measurement of the current in the branch. I could not find the correct MOSFET (IRLD024) model, instead I used the model (IRFD024) of a similar one but with a different Gate Threshold Voltage. Also as a common procedure to minimize size of the files and speed up processing, I create a smaller library file, containing only the models used. I wanted to show a waveform but since I updated my OpenSuse install to 11.2 I'm unable to print ngspice plots...

After verifying that the circuit worked, I designed the final schematic with the micro-controller and the voltage dividers of the various analog inputs.


The software was straight forward, start the high speed oscillator, start the PWM generator, read voltages, take decisions and increase/decrease PWM output. One note worth mentioning is that the ATTiny85 and the ATTiny15 have two input ports exchanged (Port PB4/PB3 - Pins 2/3) although the ADC inputs are the same!
Here is a couple of pictures of the circuit, the first charging and the second working.


SBC6120 Developments - Casing and altri

After some consideration I decided not to use the plastic casing I had bought for the SBC6120. I thought that a metal casing would be much more appropriate, I found one from Hammond that could fit the SBC and a hard disk.
I want to use the services of these gentleman to design the front and back plane, but at about 20€ per panel, I might go for the front panel only. I found the old digital equipment corporation logo and I'm using Helvetica to do the "pdp-8".
I plan to use the power adaptor and the internal power supply (+5V,+12V) from an old external hard disk casing. The point is to be able to insert in the case any type of IDE hard disk, 3.5' 2.5' or even Compact Flash.
The SBC6120/OS-8 supports a maximum disk size of 2Mbytes, so with 16Mbytes you'd have the equivalent to 8 hard disks of the time and probably be able to fit all the "interesting" software ever compiled/assembled for the PDP-8.
My problem has been finding a IDE 3.5 inch hard disk with a few megabytes, something in the range of 32/64 Mega bytes... it's becoming almost impossible to find hard drives in the Megabyte range...
So to start with something, I went with a old CF of 64 Megabytes and an IDE adaptor, the SBC6120 recognized the drive. These old CFs were bought in a "spare-parts electronics" shop for 1€.I used HyperTerminal (in Windows) and Minicom (linux) to download an disk image, but I had to change the communication protocol is 9600 baud, 7 bits, mark parity, one stop bit (9600 7M1). I also added 100ms delay after each line feed so that the SBC6120 has time to write the sector. I believe this to be a CF problem as it does not have a disk cache, probably with a real hard disk it will work without the delay.
I've downloaded an image provided in the sparetimegizmos site and the next day I checked if it had loaded ok... Boot the SBC6120, type in a DIR and wait for results... Success!! a directory listing appears...
Now I just need to finish the case, find a hard drive and learn how to work with OS-8 :-)

2009-09-27

Peppers update

My chilly crop has had its ups and downs. Some time ago the leaves of most stems where becoming yellowish and falling, latter the cause was known to be over-watering of the plants. Since reducing the water to once every three/four days (from once every day) the leaves started growing again and of a vivid green color.

When the temperatures are forecast to reach below 5 degrees centigrade during the night I bring the vase inside, otherwise most of the time the vase is outside facing southwest/west.

Nevertheless, our strange looking pepper is only now becoming reddish, it is supposed to be a Jalapeño, but it is curlier than most peppers I've ever seen. Most people don't know but before peppers become red and ripe, they go through a stage where they are mostly brown/black. Since the strange pepper is a bit bigger than most the color transition takes more time and you can see the color grading from green to red going through brown.

The leaves of this particular pepper are still yellowish, but at least they're not falling... I hope it recovers soon and reaches maturity A.S.A.P.

Meanwhile a new flower has open... so probably more peppers are expected for Christmas...

Feeding data to Pachube from Arduino

After having done the Arduino Home monitor I wanted to put data on a webpage and do some graphics. Alex suggested putting it at Pachube, as he also has some of his house data there and he had an invitation "to offer". (Thanks Alex!).
Patcube can be feed with data by your application from time to time or Pachube's server requests data from time to time to your "Web-enabled-application". Since I wanted to keep my arduino serving my "human-readable-webpages", I thought of creating a "virtual file" that would Pachube would fetch to get the data. On their Tutorial pages, Pachube has a sample application for feeding data from an Arduino to Pachube. The Tutorial example posts data to the Pachube server from time to time. Since I still wanted to keep my normal webserver and check the temperature online I decided to go the other way and create a comma separated values (csv) page that Pachube would fetch.

This was a bit more difficult than I expected. Before to any access to port 80, the Arduino would reply with my info webpage, but now I had to determine which webpage was accessed. I had to parse the GET command from the browser/server and provide the requested page.
After implementing this "virtual file system" I had another hurdle to overcome, Pachube was always complaining that my CSV page didn't have the correct format. After reading the quickstart a few more times and the http/html specification I added the correct header and an empty line at the end, and it finally Pachube started collecting data correctly.

Finally I wanted to increase the precision of the analog to digital converter (ADC) of the Arduino, specially when reading the LM35 temperature. The LM35 outputs 10mV per degree Centigrade so it will output a full volt at 100 degrees Centigrade, in order to increase the resolution of the ADC the reference voltage must be lowered to close the value in range.
The Arduino provides the option of using either an internal reference (of 1.1V), an external reference (selected externaly) or the default supply voltage (5V in the Arduino Duemilanove). The internal reference is 1.1V so it would beter to use it for the LM35, but for the Light sensor the best is the 5V reference.
So I needed to change reference between conversions, there are a couple of problems when trying to change reference. When default is selected there is a low impedance connection between the reference and the ADC, so when the reference is changed the ATMega168 datasheet says that at least one measurement will be incorrect (I do two for safety). The problem with the internal reference is that it has a high impedance connection to the ADC, so any change takes more time to charge referece input of the ADC, the problem is that the datasheet does not say how much... so I change the reference to internal first and wait for the next webpage request and do the temperature conversion first, this increases the precision of the measurements if the webpage requests are not too frequent.

/*
* Web Server
* based on the original webserver example.
* processes the GET command from the http client.
* supports two pages, one readable for humans /info.html other in CSV for computers /csv.html
*/
/*
*==== Typical HTTP request ====
*GET / HTTP/1.0[CRLF]
*Host: www.google.com[CRLF]
*Connection: close[CRLF]
*User-Agent: Web-sniffer/1.0.29 (+http://web-sniffer.net/)[CRLF]
*Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7[CRLF]
*Cache-Control: no[CRLF]
*Accept-Language: de,en;q=0.7,en-us;q=0.3[CRLF]
*Referer: http://web-sniffer.net/[CRLF]
*[CRLF]
*==== Typical HTTP request ====
*/

#include <ethernet.h>
#define DEBUG

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 2, 253 };
//These were not needed, i.e. without them the ethernet shield works ok with my router
//byte gateway[] = { 192, 168, 2, 254 };
//byte subnet[] = { 255, 255, 255, 0 };

// handle requests at port 80
Server server(80);

// values of temperature and light
long tmprtr,lght;

char cmmnd; /* received command = {G|P} for GET or PUT */
char args[20]; /* requested file,arguments */
char host[20]; /* host ip address*/

void setup()
{
Ethernet.begin(mac, ip);
server.begin();
#ifdef DEBUG
Serial.begin(9600); // serial port for debug
#endif
}

//
// Get and convert analog input values
//
void get_values(void)
{
tmprtr=((long)analogRead(0)*1100)/1024;
analogReference(DEFAULT);
analogRead(1); /* discard value */
analogRead(1); /* discard value */
lght=(long)analogRead(1)*1000/1024;
analogReference(INTERNAL);
analogRead(0); /* discard value - see ATMEGA168 datasheet on change reference */
analogRead(0); /* discard value - for safety*/
}

//
// Begin of HTML page, fixed page title
//
void http_head(Client & client)
{
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.println("<html>");
client.println("<title>Arduino Home monitor</title>");
client.println("<body>");
}

//
// End of HTML page
//
void http_end(Client & client)
{
client.println("</html>");
client.println("</body>");
}
//
// reply to root request or /info.html
//
void http_root(Client & client)
{
http_head(client);
client.print("Temperature is ");
client.print(tmprtr / 10);
client.print(".");
client.print(tmprtr % 10);
client.println("<br />");
client.print("Light at home is ");
client.print(lght/10);
client.print("%");
client.println("<br />");
http_end(client);
}
//
// reply to /csv.html
//
void http_csv(Client & client)
{
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/csv");
client.println();
client.print(tmprtr / 10);
client.print(".");
client.print(tmprtr % 10);
client.print(",");
client.println(lght/10);
client.println();
}
//
// Work on a http reply, check request file, produce output
//
void http_reply(Client & client)
{
#ifdef DEBUG
Serial.println("==== debug out ===");
Serial.println(cmmnd);
Serial.println(args);
Serial.println(host);
Serial.println("==== debug eot ===");
#endif
get_values();
if ((args[1]=='c') && (args[2]=='s') && (args[3]=='v')) http_csv(client);
else http_root(client);
}

void loop()
{
Client client = server.available();
#define LN_BUF 40
char inp_ln[LN_BUF]; /* input line, crop at 40 chars */
char chr; /* input char */
byte inp_ln_ptr,i;

if (client) {
inp_ln_ptr=0; /* line is empty */

while (client.connected()) { /* while client is connected process lines */
if (client.available()) { /* is there a char available */
chr = client.read(); /* get it */
if (chr == '\n' && inp_ln_ptr<2) {
http_reply(client); /* received a blank line, create return page */
break; /* exit while, !! find a more logical way to do this */
}
if (chr == '\n') { /* end of line */
inp_ln[inp_ln_ptr]=0; /* end of line */
Serial.println(inp_ln);
if ((inp_ln[0]=='G') && (inp_ln[1]=='E') && (inp_ln[2]=='T')) {
cmmnd='G';
// get arguments
for (i=0;i<sizeof(args);i++) {
args[i]=inp_ln[4+i];
if (args[i] == ' ') break;
}
}

if ((inp_ln[0]=='P') && (inp_ln[1]=='U') && (inp_ln[2]=='T')) {
cmmnd='P';
// get arguments
for (i=0;i<sizeof(args);i++) {
args[i]=inp_ln[4+i];
if (args[i] == ' ') break;
}
}
if ((inp_ln[0]=='H') && (inp_ln[1]=='o') && (inp_ln[2]=='s') && (inp_ln[3]=='t')) {
// get arguments
for (i=0;i<sizeof(host);i++) {
host[i]=inp_ln[5+i];
if ((host[i] == ' ') || (host[i] =='\n') ||(host[i] =='\r')) {
host[i]='\0';
break;
}
}
}
inp_ln_ptr=0; /* ptr ready for next line */
}
else if (inp_ln_ptr<LN_BUF-1) inp_ln[inp_ln_ptr++]=chr;
}
}
// give the web browser time to receive the data
delay(1);
client.stop();
}
}

When mounted horizontally the Ethernet shield and the voltage regulator produce enough heat to raise the temperature in the sensor to about 30 degrees Centigrade. When placed vertically convection keeps the heat away and the sensor reads more "normal" temperatures.
The Power supply of the Arduino is supplied by the router that has a USB port, this way an extra wall-adapter is not needed.
The pachube feed is here, where you can see both graphics light and temperature. It is also possible to embed the sensor readings in the blog layout...

2009-09-15

Building GCC toolchain for AVR

Recently, along with my Arduino-ethernet-shield I bought a Arduino-Diecimilia fitted with a ATMega328, only to find out that my compiler set-up wouldn't work. A quick investigation (here and here) showed me that my current gcc toolchain (4.2.2) didn't support the '328.
OpenSuse repositories provide an avr-gcc toolchain that can be used with the Arduino IDE for Arduinos fitted with the ATMega8 (very old) to the ATMega168 (old), for the ATMega328 you must build the toolchain yourself (at least for now).
I tried to follow general cross gcc building instructions (more on this on another day), but it didn't work. Using gcc bleeding edge of technology sometimes has its problems. Also there are some patches that must be applied to the source.
So I decided to follow the build script provided by the AVR-Freaks forum. You must become a member in order to download the script. It is still not the latest version of GCC 4.4.1, but it is recent enough (4.3.3) for ATMega328.
The pre-requisites are quite important, you can install binutils-devel (BFD support) from the Opensuse repositories and download the mpfr from here. Compile and install mpfr.

$./configure
$make
$su
#make install
#exit
$

Then run the scripts in order:

$ ./getfiles.sh
$ ./get-patches.sh
$ su
# ./buildavr-no-insight.sh
# ./buildinsight.sh
# exit
$

The build scripts ask you a couple of questions and in the end suggest some clean-up, once it starts you have time for few coffees...
Finally test your configuration:

$ avr-ld -v
GNU ld (GNU Binutils) 2.19.1 + coff-avr-patch (20050630)
$ avr-gcc -v
Using built-in specs.
Target: avr
Configured with: ../../source/gcc-4.3.3/configure -v --target=avr --disable-nls --prefix=/usr/local/avr --with-gnu-ld --with-gnu-as --enable-languages=c,c++ --disable-libssp --with-dwarf2
Thread model: single
gcc version 4.3.3 (GCC)

And you're good to go...

UPDATE: 2011.03.13
I recently installed OpenSUSE 11.3 and redid the installation. It works very well but you still need to do the following (these changes are, or may not be OpenSUSE specific):
- as su create and edit a /etc/bash.bashrc.local, add the following lines:

# User specific environment and startup programs
PREFIX=/usr/local/avr
export PREFIX

PATH=$PATH:$HOME/bin:$PREFIX/bin
export PATH

This will enable all users to access the build tools.
Then you need to do the following:

# chmod 777 /var/lock
# chmod 777 /dev/ttyUSB0
# chmod 777 /dev/ttyS0
# chmod 777 /dev/ttyS1

these last two are for my serialports.. I need to remind myself of doing it for minicom.
and finally create a udev rule for avrisp mk ii.
created a file 89-usbprog.rules in the rules.d directory (as su) and add the lines:

# udev rules file for some usb connected mcu programmers

# Atmel devices
#
ATTR{idVendor}=="03eb", ATTR{idProduct}=="2104", MODE="0666", GROUP="users", SYMLINK+="avrispmkII"
ATTR{idVendor}=="03eb", ATTR{idProduct}=="2103", MODE="0666", GROUP="users", SYMLINK+="avrunknown-%n"
ATTR{idVendor}=="03eb", ATTR{idProduct}=="2107", MODE="0666", GROUP="users", SYMLINK+="avrdragon-%n"

# Microchip devices
#
ATTR{idVendor}=="04d8", ATTR{idProduct}=="0033", MODE="0666", GROUP="users", SYMLINK+="pickit2"

as seen here with minor adaptations and your done...
test it with the arduino-IDE, compile and download the blink example.
test avrisp with a simple command:
avrdude -p t15 -c avrisp2 -P usb

PS. this solution also works

2009-09-13

Arduino Home Monitor

Last week I received my Arduino-Ethernet-shield, although I couldn't use my Decimillia with it (due to a compiler problem), I went ahead with my old NG in order to try it out.
I've build a simple system with a LM35 temperature sensor connected to analog input 0(zero) through a low pass filter (100K/ 100nF) , to measure the ambient temperature.
To measure the ambient lighting I connected to the analog input 1 to the middle point of a simple LDR circuit (LDR in series with a 10K resistor, middle point connected to analog input).

The ethernet shield was the first one issued, based on the W5100 ethernet TCP adaptor. Some of the TCP stack is processed in the W5100 so the Arduino spends less time processing the packets and has some more time to do what you want him to do. Also the libraries included in the Arduino IDE work "out of the box". I added my "breadboard" shield on top of the ethernet shield plug in and went on to try it out.


My program is based on the original "ethernet/analog input" example but I had to do some calibration and conversion from the sensors.
I also tried to change the analogReference during runtime, but I didn't get good results. The LM35CZ output will change from 200mV to 300mV, for 20 degrees centigrade to 30 C respectively, therefore I would get the best of the ADC resolution if I used the INTERNAL reference of 1.1V. For some reason the values were not stable, so I abandoned it and used the 5V reference (DEFAULT) for both measures.
I also tried to "correct" the HTML output so that it could be read by a friend's Freecom MusicPal, but we never made it. I need to learn a bit more of HTML parsing and building the page.
Here is the code:

/*
* Web Server
*
* A simple web server that shows the value of the analog input pins.
*/

#include <ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 2, 253 };
//byte gateway[] = { 192, 168, 2, 254 };
//byte subnet[] = { 255, 255, 255, 0 };

Server server(80);

void setup()
{
Ethernet.begin(mac, ip);
server.begin();
}

void loop()
{
long tmp;

Client client = server.available();
if (client) {
// an http request ends with a blank line
boolean current_line_is_blank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// if we've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so we can send a reply
if (c == '\n' && current_line_is_blank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.println("<HTML>");
client.println("<title>Arduino Home monitor</title>");
client.println("<BODY>");
// output the value of each analog input pin

client.print("Temperature is ");
analogReference(DEFAULT);
delay(10);
tmp=((long)analogRead(0)*5000)/1024;
client.print(tmp / 10);
client.print(".");
client.print(tmp % 10);
client.println("
");

analogReference(DEFAULT);
delay(10);
client.print("Light at home is ");
tmp=(long)analogRead(1)*1000/1024;
client.print(tmp/10);
client.print("%");
client.println("
");

client.println("<BODY>");
client.println("<HTML>");
break;
}
if (c == '\n') {
// we're starting a new line
current_line_is_blank = true;
} else if (c != '\r') {
// we've gotten a character on the current line
current_line_is_blank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
client.stop();
}
}

P.S. I had to change the > and < by the html code & g t ; and & l t ; so I don't know if the above code will cut/paste correctly.
Most of my problems were in fact related to the my provider's ADSL access box, it has only one fixed IP address available x.x.x.253 (it must be outside the DHCP range, which I cannot change), and then enabling the routing of port 80 from the outside world to the Arduino in the inside network.
With my IP address I can check the temperature and light levels (?) at home from any computer!(possibly later I could use a free dynamicdns)...
All this in the same weekend we place a new kitchen floor...
Uf... I though it never ended...

2009-09-08

The Origin of Species

Finally I had the time and patience to finish it... It was hard but I got to the end at last! To all those future readers of Darwin's book a few words of advice:
- spare a couple of months, it is not easy ready as there is no action, it is basically a Ph.D. thesis presenting the Hypothesis of evolution and rebating some old (or still existing in revised form) different points of view.
- Naturally the book is biased towards the concept of evolution, when reading try to have an open mind and place yourself in Victorian times.

It was hard but fun, I must admit that I am surprised not only on how our knowledge has evolved (pun intended) but also how some things we now know for sure, were still unexplained at the time.
In the book Darwin suspects that earth started as continuous continent and only later the continents have separated, in order to explain the same species in different continents or in distant islands, we now call it the plate tectonics theory.
The markings in the book are to avoid dog ears in the pages, I try to mark important passages as I go through the book and later revise them..

2009-08-06

Arduino NG rev. c

About a year and a half ago I bought my first Arduino, it was a Arduino NG. At the time it was quite new by the fact that it had a USB port. I did a lot of experiments with it, borrowed it a couple of times and now it is back home.
I never used it with external power until one day I wanted to do an autonomous robot. I programmed some test code, removed it from the USB port, powered the auxiliary power supply (a.k.a 9v battery) and nothing...
The usual debugging technique followed:
- test program with USB, it worked.
- remove from USB, change switch to external, power external and wait...wait..nothing.
- check the web... I found here that the problem existed and already had a solution.
- while browsing "problem Arduino NG" I also found here that the "autoreset" feature of the diecimila had been implemented.
So I picked up the soldering iron, my pack of SMD components and went on to hack the board. So I changed the 3rd resistor from the top and I placed the capacitor just below the RX Led (a reader told me it was very clear what I had really done to the board...)
Here is the final result:

2009-08-03

Harvesting the Carrots

Last Weekend we decided to Harvest my carrots from the vase. When we came back from a week away we noticed that they were not growing that much. We thought that they must have reached their limit in the vase so...it was harvest time... and we were in for some surprises...

The first one out of the vase was "Quasimodo", because we transplanted the carrots some of them had grown into strange forms. Lesson learned.... do not transplant carrots...

This one we really don't know what to call it... or... we do but it's not nice...they are actually two carrots that started in the same yogurt cup and ended up knotted together.Here's a picture of the whole crop, not bad for a single vase. Last but not the least:
This is the way the world ends,
this is the way the world ends,
this is the way the world ends,
not with a bang but with a chicken stew (at least for our carrots).

2009-07-25

Back from Holidays - Frappé

This year we went to Greece, Crete in particular, for our summer get away. It was fantastic, great beaches, great landscapes, great food, great weather, all this and you still can visit some impressive archaeological sites.



It has been some time since I posted about coffee, probably because other than being "surprised" by the excessive price of an expresso, nothing of notice happens outside...
Well in Crete I've found what is probably the only good use of instant coffee... meet the Frappé!.
This is how I do mine, I've talked to some Greek friends and they do it a bit differently...
Put the instant coffee (one or two spoons) and some sugar (with sugar you can do more foam) in a glass and add a few drops (or a table spoon of water).

Use the an electric whisk until you a get a foamy cream.

Whisk until the foam starts getting white in colour.

Add water and ice, a straw and you're done... Instant frappé!

2009-07-07

Summer Solstice

According to Wikipedia this year's solstice was on the 21st of June and it was the "official" begin of the summer. My peppers finally blossomed and I was waiting to get more peppers and earlier than last year. I still hand pollinate them as on this high floors bees or the like are very scarce, on the other hand, Ana's tomatoes just need some wind...


We were having some bugs attacking our crops, specially the parsley, celeriac and the peppers. I took a picture of them and then tried to find something similar on the web. I was also looking for advice on how to biologically get rid of it, since we actually intend to eat our products we didn't want to used any harsh chemicals. The appeared to be an Aphid, but I was not sure it looked more like this one. Here's a picture of a celeriac leaf with the pest.

As with all my plants problems I called mum and dad, experienced "farmers and plant growers", for a cure.... And they delivered, mix the ash of a full ashtray with water, mix it well, filter it through a cloth, put it in the sprayer and "splash them all".
As we are not smokers, I asked Tiago to collect his cigarette ash.. He definitely is not smoking that much (which is very good for him!), this was what he collected in two weeks.


I mixed it with water, filtered it through the cloth, then place it in the sprayer and off I went... A lean, mean, bug killing machine.

Two weeks after, the plant is alive (although the leaf in question has almost dried) and the bugs are gone!
Just great! Many thanks to Tiago, "without whom none of this would be possible" (sort off :-).

Meanwhile my carrots are also growing steadily, some of the tops are popping out... can't wait to get them out... but I need to leave them by one more month...

2009-06-02

My DRAM circuit works!

Well, after some tests I'm confident that my 8085 DRAM interface is working properly!
My first test executed from EPROM and at the end of every instruction fetch cycle does a CAS-before-RAS (C-B-R) refresh.
The second test wrote a value to the DRAM and latter read it back, still executing from EPROM, a C-B-R refresh was done at every instruction fetch.
The third test I tried writing once and read many times, and if at some point the values differed halt the processor (this would terminate refreshing). It worked, no Halts!
On the fourth test I decided to go a bit more ambitious, not only I initialized the stack to the DRAM I also placed a RET instruction in the DRAM. The program in the EPROM would then call the RET instruction and return to EPROM. This would trigger an instruction fetch in the DRAM and respective hidden refresh.
Here's a picture of the execution of the RET instruction and respective hidden refresh, top signal is RAS bottom is CAS.


Done, my "home-made"dynamic ram refresh circuit works, now I'll have to try with other microprocessors...

2009-05-24

Solar Cells testing

This Sunday the sky was clear and the Sun strong, so I decided to check some of the solar cells I had in my components box. I have two types from solarbotics (this one and this other one) and other from pagermotors (this one).


All the cells are up to specification although I only tested them on open circuit voltage, it was too hot and too bright to do a test load. I also have no reason to believe the cells won't perform as specified.
I have two ideas for them:
  1. use one or two white bright LEDs and a couple of batteries to build a "light hours" extender for my chili peppers. I haven't decided yet if I'll use a micro-processor or I try to build a fully analog control system. Either way it will be quite complex as it involves two switching power supplies (charge batteries and supply LEDs) and some operation decision. I'll call this project the "Solar-Extender".
  2. revise the Mousebot to include a solar panel and a couple of rechargeable batteries, this one will definitely have a micro controller. It should harvest the sun and charge his batteries and when the sun is out it should hide in the darkest and coolest place of the house. Put some "simulated annealing" when it wake's up or goes to sleep in order to let him fool around and find some better places. This project I'll call the "Solar-Bug".
I hope to finish these two projects before the end of the summer, as from then on either the behavior of both the projects will be pushed to the maximum efficiency as light-hours decrease towards the winter-equinox.

8085 DRAM interface (30 pin SIMM)

After seeing this project on Make (or here) I felt like old DRAMs could have a better use... It is a bit sad that so much technology and development by semiconductor engineers and computer designers goes "wasted" on a light box. The light box looks good, don't get me wrong.. but.. so much engineering wasted in a light box... doesn't look right.
I always thought that using these SIMMs in microprocessor applications would be interesting and with the proper memory management it could be used with old 8 bit microprocessors. The likes of Z80, 8085, 6809, 6502 could go with a simple DRAM interface.
Trying to search for information online or even in books, application notes etc is quite elusive, there are three good sources of information:

  • This one (or here in pdf) is very specific regarding the Z80, and Z180...[...]

  • This one with a PIC processor connected directly to a DRAM chip (source code only).

  • And this one, where a FPGA and a 8051 microcontroller are connected to a 72 pin SIMM.

  • Most of the microprocessor or microcontroller projects online either use one or more large SRAMs (128K,256K and 512K bytes) are these are nowadays readily available.

    Although my projects don't need a large RAM size I wanted to probe the use of old SIMMs with the 8085. The Z80 makes it all a bit more simpler because it has been design to use DRAMs, so at the end of the instruction fetch cycle the RFSH and MREQ signals go low, the problem with this that the instruction fetch cycle is slightly (half cycle) shorter (see here).

    It seems logical the one would try to do the same in a different processor, while the processor is decoding and executing the fetched instruction the DRAM controller preforms a DRAM refresh, this way every instruction fetch a refresh is performed which normally is often enough. Except, in the 8085 case, if the processor is halted. The Z80 solved this problem by still performing instruction fetches during HALT (it executes NOPs). I decided to carry on accepting this problem and do not write any programs that halt to processor unless I want to lose the contents of the DRAM.

    In the 8085 there's no refresh cycle, but at the end of every instruction fetch, during 1 to 3 cycles (depending on the instruction just fetched), the CPU relinquishes the bus, these are called T4,T5 and T6 states (see here). Although a single cycle for refresh might not seem a lot, one could extend the cycle a bit more until ALE goes high, from then on the address on the bus is valid and a normal fetch should be made.

    The 8085 does have an slight advantage when compared to the Z80 (and Z8000), the read signal and write signal (RD and WR) are active for the same time weather in instruction fetch, memory read and or memory write (and even I/O these are extended in the Z80), so there's no need for a early-write signal when using the SIMMs.

    I designed the circuit as a combination of two sequential circuits, one generating RAS, CAS and Address inputs during a normal read/write and instruction fetch (accessing), and another circuit for refreshing the RAM on every instruction fetch (refreshing). During a instruction fetch from a non-selected memory the last cycle is used to do a CAS before RAS refresh, if the fetch is done from the DRAM, the access cycle is extended to do a hidden refresh (toggle of RAS line while CAS is low). When ALE goes high all DRAM access activities stop and the circuit waits for RD or WR to go low to start the RAS/Address Mux/ CAS sequence. I use the X2 output from the 8085 because it is at 2 times the CLK output, therefore it allows faster state switching and a longer memory access time.


    I've designed and assembled the circuit and I'm about to do extensive testing if it really works or not. Here's the schematic of the CAS/RAS generation, the connection to the SIMM is straight forward, the pin-out of a 30-pin SIMM is here, and some of the history of SIMM development is here.


    The 8085 is clocked at 8MHz, and on the oscilloscope RAS appears on top and CAS on the bottom. My only problem has been my EPROM emulator, and I need to do something about that in the future. It is only working in DOS... So now I need to do all the programming in DOS and test the system with the oscilloscope. I'm also using the SOD line to trigger the oscilloscope when the SIM instruction is executed, the current program is the following (beware, 8085 assembly follows):

    .title test_program 0
    .sbttl testing

    .area ram(abs,cseg)

    .org 0x0000
    reset:
    di
    lxi h,0xC000
    lp000:
    mvi a,#0xC0
    sim
    mov a,m
    jmp lp001
    lp001:
    mvi a,#0x40
    sim
    mov m,a
    jmp lp000

    SBC6120 Update

    This weekend I started with the finishing touches to my SBC6120. I found what appears to be a "suitable" casing for the board, a power supply and the disk drive.
    I would like to build inside a 12V and a 5V switching power supply from a 16-24V DC input, this power supply would allow the system to support either common 3.5 inch IDE drives or the smaller 2.5 inch laptop IDE drives (5V only).
    I also need a power switch, a reset switch, access to the status indicators and a DB9 serial port connection.
    For now I'm using a 1.4 inch IBM X40 drive and everything appears to fit. I would rather have a bit more room, but the next available case was too big.
    I haven't gave up on finding the "best"case, but for that I still need to find a suitable power supply, a some nice looking panel switches (ON/OFF and RESET) and the serial connector.
    An old chopping board is not the best background for an electronics project... but then again.. It's what I had at hand..

    Follow up on Balcony garden

    Our vegetables have been growing steadily for the past two weeks. I've been moving some of the sprouts that were born in the yogurt cups to the bigger vases, but now I don't have any more space. On some, instead of removing them from the cup, I just cut the cup bottom and push them into the vase.

    I learned that carrots don't like and should not be moved! No wonder now that they took so long to adapt, on the other hand tomatoes, kale and the celeriac don't seem to bother being moved and are developing nicely.
    On the "battle of the veggies" I seem to be up front in the kale, celeriac and carrots, unfortunately my tomatoes look like little dwarfs compared to Ana's..

    Last week my kale reached some "maturity" and before it became too hot to eat a soup we decided to try doing a caldo-verde.

    We used some of the bigger leaves of our kale to do it, with some "chouriço" and bread, hum ... delicious...