Reset a program from a ‘freeze’

While doing a test run on software for an incubator the software did fine, until suddenly on the ninth day weird things started to happen: the LCD showed some odd data and in spite of a low temperature the heating had not kicked in. I resetted the software, wondering what it could be but only an hour later again something off happened. This time in spite of the temperature being well over the upper limit, the heating was not switched off.
I checked my code, which really wasn’t so complicated: Read DSB1820, read DHT11, compare with high and low limit, switch a pin on or off and write the value to an LCD and I couldn’t find a single mistake and don’t forget, it had run flawlessly for 9 days. I suspected my display. This was a 20×4 LCD with I2C module with 4k7 pull up. Nevertheless there might still have been some ‘static’ on the SDA and SCL lines that supposedly can cause the Arduino to freeze.

Obviously that is not good if you are running an incubator as you dont want to check it and find your eggs boiled.
So, other than maybe straightening out the LCD cables a bit, I decided that I needed some software protection against ‘freezes’
The only (and possibly best) way to do this is with the watchdog timer. I dont want to go into the specifics and the background of the watchdog timer, but just keep it on a practical level.
What we do is to set-up the watchdog timer to initiate a system reset after say 4 seconds. Then in our loop we do a reset of the watchdog timer so it starts counting from zero again. So as long as the program tells the watchdog timer “I am still running” nothing will happen. Should the program freeze up, it will not reset the watchdog timer and then after 4 seconds the watchdog timer will reset the entire system.
It is very well possible to use the watchdog timer by manipulating the various registers yourself, but it is much simpler to use the watchdog libary that is part of the avr libraries.
We do this as follows:

#include <avr/wdt.h>

void setup()
{
	wdt_disable();
	//wdt_enable(WDTO_1S);// 1 sec
	wdt_enable(WDTO_2S);// 2 sec
	//wdt_enable(WDTO_4S);// 4 sec
	//wdt_enable(WDTO_8S);// 8 sec
}

void loop()
{
	wdt_reset();
	//  your program
	........
}
Advertisement

1 Wire LCD interface: Part 1

The one wire LCD interface has been around on the internet for some time already and made popular by Roman Black, although he claims he is not the inventor of the principle. His article is mainly PIC processor oriented, but it gives a good explanation of the principle. Myke Predko is also a name that  should not be unmentioned as pioneer in 1 wire LCD driving. Also this article about  one wire driving of a shift register is very informative

The ShiftRegLCD123 website from Raron used to give a lot of information as well, along with circuits, but that (the Wiki) seems to have disappeared. But his library is in codebender.

In brief, the One Wire interface uses a latched shift register in which the clock and the latch are taken from the data signal through two RC networks that produce the necessary delay. Circuits are a plenty on the interweb, but finding the proper driver for it can be confusing sometimes.

Although the interface on the data, clock and latch lines is rather standard, the connection between the shift register and the LCD has thre major variants that for now i will just call the Roman Black, the LCD3Wire circuit (yes, it is 1 wire) and the ShiftRegLCD123 circuit. Also Elektor has published a 1 wire interface (Detlef Hanemann)(Published in issue 9/2015 on page 92) with yet again a different shift register to LCD connection. Their setup is said to have several advantages over the setup used by Roman Black, it uses the Q7′ direct output of the shift register to trigger the output latch register to carry over automatically the shifted data to the output pins. But for that it requires a monoflop built around a BS170 FET to generate the E-pulse. The setup to be used in Francisco Malpartida’s LCD library is yet again different from the other 3 and uses a diode to create an AND gate

1wireLCD
Roman Black

1wireLCD-shiftreglcd

ShiftRegLCD123

1pinlcd-elektuur
Elektuur

onewiremalpertida

 

Malpartida LCD library

. Roman Black LCD3Wire Shiftreglcd Elektuur Malpartida
RS  Qc  Qb  Qc  Qg  Qg
R/W  GND  Qc  GND  GND  GND
E  Qd  Qd  Qh  Qh’  Qh’ sort of
D4  Qe  Qh  Qd  Qa  Qe
D5  Qf  Qg  Qe  Qb  Qd
D6  Qg  Qf  Qf  Qc  Qc
D7  Qh  Qe  Qg  Qd  Qb

Driving these OneWireLCD’s thus differs per configuration. The ShiftRegLCD123 library can do both the ShiftRegLCD and the LCD3Wire protocol. The Liquid Crystal Library of Francisco Malpartida  does have a One Wire protocol but make sure you have the latest version. However, it relies on connections different from the others mentioned:
// Bit #0 (QA) – not used
// Bit #1 (QB) – connects to LCD data input D7
// Bit #2 (QC) – connects to LCD data input D6
// Bit #3 (QD) – connects to LCD data input D5
// Bit #4 (QE) – connects to LCD data input D4
// Bit #5 (QF) – optional backlight control
// Bit #6 (QG) – connects to RS (Register Select) on the LCD
// Bit #7 (QH) – used for /CLR on the HW_CLEAR version (cannot be changed)
// (Q’H) – used for Latch/EN (via the diode AND “gate”) (cannot be changed)

// -----------------------------------------------
//
//                         74HC595     (VCC)
//                       +----u----+     |          2.2nF
// (LCD D7)------------1-|QB    VCC|-16--+      +----||----(GND)
// (LCD D6)------------2-|QC     QA|-15         |
// (LCD D5)------------3-|QD    SER|-14---------+--[ Resistor ]--+
// (LCD D4)------------4-|QE    /OE|-13--(GND)         1.5k      |
// (BL Circuit)--------5-|QF    RCK|-12---------+                |
//                       |         |             \               |
// (LCD RS)------------6-|QG    SCK|-11-----------)--------------+--(Seri
//                     7-|QH   /CLR|-10--(VCC)   /               |
//                  +--8-|GND   Q'H|--9---|<|---+--[ Resistor ]--+
//                  |    +---------+     diode  |      1.5k
//                  |                           |
//                  |      0.1uF                |
//                (GND)-----||----(VCC)         +----||----(GND)
//                                              |   2.2nF
// (LCD EN)-------------------------------------+
// (LCD RW)--(GND)
//

The Elektuur/Elektor configuration has its own program, or here (both direct download link)

I2C for LCD

IMG_20141108_161103A cheap I2C expander aimed at LCD’s is available from a multitude of sources such as eBay or DealExtreme (http://www.dx.com/p/lcd1602-adapter-board-w-iic-i2c-interface-black-works-with-official-arduino-boards-216865). The pin-out from this interface matches the pin-out from most Hitachi based LCD’s and therefore can easily be connected, just make sure that the pin’s are not connected in reverse.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Gnd Vcc Vlcd RS RW E D0 D1 d2 D3 D4 D5 D6 D7 Anod Cathode

After downloading and installing the library from F. Malpartida, use the following program to test

/*
P4 R/S
P5 RW
P6 E
P0 D4
P1 D5
P2 D6
P3 D7

A4=SDA 
A5=SCL
*/
#include  <Wire.h>
#include  <LiquidCrystal_I2C.h>
#define BACKLIGHT_PIN     3
#define I2C_ADDR 0x27 
LiquidCrystal_I2C lcd(I2C_ADDR, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
// Create a set of new characters
const uint8_t charBitmap[][8] = {
   { 0xc, 0x12, 0x12, 0xc, 0, 0, 0, 0 },
   { 0x6, 0x9, 0x9, 0x6, 0, 0, 0, 0 },
   { 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0, 0x0 },
   { 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0, 0x0 },
   { 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0x0 },
   { 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0x0 },
   { 0x0, 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0x0 },
   { 0x0, 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0x0 }
   
};

void setup()
{
   int charBitmapSize = (sizeof(charBitmap ) / sizeof (charBitmap[0]));

    
  lcd.begin(16,2);               // initialize the lcd 
// Switch off the backlight
noBacklight()

   for ( int i = 0; i < charBitmapSize; i++ )
   {
      lcd.createChar ( i, (uint8_t *)charBitmap[i] );
   }

  lcd.home ();                   // go home
  lcd.print("Hello, ARDUINO ");  
  lcd.setCursor ( 0, 1 );        // go to the next line
  lcd.print (" FORUM - fm   ");
  delay ( 1000 );
}

void loop()
{
   lcd.home ();
   // Do a little animation by writing to the same location
   for ( int i = 0; i < 2; i++ )
   {
      for ( int j = 0; j < 16; j++ )
      {
         lcd.print (char(random(7)));
      }
      lcd.setCursor ( 0, 1 );
   }
   delay (200);
}

The standard address on the I2C bus for this model is 27H. In case you need/want to change that, you need to connect the A1-A3 lines to ground: either 1, 2 or all 3 of them. The table below  shows what adresses correspond with what  connections. You will find solderpads  of these addresses on the board.
pcf8574end

Nokia 5110 display on Arduino

The Nokia 5110 LCD module is a small and cheap LCD with a lot of graphical possibilities and is quick to add to projects that need a display. The programming of the display is a bit difficult but there are a number of very good libraries available. Adafruit ofcourse has a library that is available here: here you will also need to install the GFX library that library is a bit slow but a faster hardware SPI library by Snigelen is available here: here.
Some additions to the Adafruit library have been made by avdweb
The arduino playground has a library: here
A library is also available: here
A further fast libray is available here with explanation here
Also a library by Henning Karlsen

The display driver is a PCD8544 chip, and it runs at 3.3V so you will need a 3.3V supply handy. Logic levels must be 3.3V to prevent damage so you must use some kind of level shifter (such as a 4050) or some resistors. It is possible to use a number of different lines to hook up the LCD. Normally it is 5 lines, but a configuration with 4 or even 3 lines is possible The Nokia 5110 LCD has 5 control lines; the interface is of the type SPI.

For a good understanding of how to hook up the Nokia LCD, it is good to understand that it is an SPI device.
Apart from power and ground (and power to the LED backlight if there is one) There are four basic signal lines to an SPI device. They are

  • MOSI (Master Out Slave In) also known as SIMO and SDI; DI, DIN, SI: because it is Serial Data In. It lets the master send data to slave.
  • MISO  (Master In Slave Out) aka SDO; DO, DOUT, SO which allows the slave to send data to the master. It isn’t always there.
  • SS  (Slave Select) also known as SCE, nCS, CS, CSB, CSN, nSS, STE which switches sending between master and slave.
  • SCLK  which is the clock pulse.

The Nokia5110 LCD has no MISO signal, but it has a:

  • D/C which selects between data and commands being sent.

and ofcourse:

  • RST  (Reset)
  • GND
  • Vcc which needs 3.3V

As long as you are using the Nokia LCD stand alone you are rather flexible in choosing what pins to use, however, if you want to use it in combination with another SPI device on the hardware SPI bus, you must use the proper SPI pins and you cannot use the MISO for any of the Nokia LCD pins as it has no MISO
The proper connection would be:
MOSI ->  MISO  (D12)
SCLK -> SCK (D13)
SS -> an available pin on Arduino, other than D11, traditionally D10 or D8 are used
D/C -> an available pin on Arduino, other than D11
RST -> an available pin on Arduino, other than D11, or an auto reset

Mostly, when no other SPI devices are used, the chip select can be connected to the GND, so 4 control lines remain. As said, it is possible to use only 3 control lines, by connecting the Nokia reset pin to the Arduino reset. This works only when the serial monitor is used, not with a standalone Arduino.

Another possibility is to generate a reset pulse on power up automatically, with a RC combination, to save one control line to the Arduino. This solution doesnt seem to be reliable though. The proper functioning seems to also depend on the capacitor across the 3.3V supply. Using only 4 or 3 lines of course only makes sense if your library allows that, otherwise the pins may not be connected but will be in use by your program. The Device  can tolerate a Vcc of 5 Volt, but it works best at 3.3Volt. When using it with a 5 Volt device, it is best to either have a level adapter or  resistors between the two devices.

 

nokia5510-4050

Example of connection with resistors and 4 control lines

 

handy article

I2C interface for LCD

lcd_i2CThe PFC8574 and the PFC8574A are  I2C port expanders that can be uses to connect a parallel LCD to the I2C pins of the Arduino (or other microcontroller)

The PCF8574 has addresses ranging from 0x20 to 0x27 (up to eight PCF8574 devices may be used on the same I2C bus). It’s address  is 0100aaay with ‘ aaa’ being the address bits and ‘y’ being the Read(1)/Write(0) bit.
The PCF8574A has addresses ranging from 0x38 to0x3F (up to eight PCF8574A devices may be used on the same I2Cbus). 0x38=0011 1000 (all tied to ground)  and 0x3F=0011 1111 (all tied to ‘HIGH’) hand
Addressing takes place with 3 address pins that can be taken high or low and that form the bottom 3 bits of a 7 bit address register (the 8th bit, the least significant bit is the R/W bit).
PCF8574: 0100A2A1AScreenshot from 2014-01-14 15:57:350  0100000 =0x20; 0100111=0x27
PCF8574A: 0111A2A1A0 0111000 =0x38; 0111111= 0x3F
The /INT pin is an open drain output that can be used to trigger events.

Library that can be used is the newLCD library by Malpartida: https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads

Can define two lcd’s

LiquidCrystal_I2C lcd1(0x20,16,2); // set the first LCD address to 0x20
LiquidCrystal_I2C lcd2(0x21,16,2); // set the second LCD address to 0x21

Initialize them in the setup-section:

lcd1.init(); // initialize the 1st lcd
lcd2.init(); // initialize the 2nd lcd

And send text:

lcd1.print("1st Hello!");
lcd2.print("2nd Hello!");

That’s all.

lcd_plan2
NOTE
Though it is always fun to build something yourself. In this case it might not be worth it: consider this ready built board from DealExtreme.com. for only 1.80 euro you will have the complete board, inclusing headers that will solder right into most LCD’s. The PCF8574P as chip alone, will cost you an average of 2.10 euro

Two wire Interface for LCD-with shift register

P1050315e lcdshiftUsing an LCD for a microcontroller such as the Arduino takes up quite a number of pins and actually doesn’t leave that much pins for other tasks. There are various solutions, like using an HC595 shiftregister (requiring three wires), a PCF 8574 or MCP23008 to create an I2C option or using a shift register such as the 74LS164. The added circuit does just that. It works on an Attiny85 as well.

A Library (by Malpartida) supporting this circuit can be found here: https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads

A 100nf decoupling capacitor is necessary and should be placed near the  IC. Shiftregisters as the 74LS164 cause sudden changes to the current drawn from it’s power, and hence introduce noise. To counter this, a “decoupling capacitor” should be used as close to the shiftregister power pins as possible (Vcc and GND). Otherwise, the shiftregister may get faulty data and then the LCD won’t work as intended. This is also dependent on other factors, like wire lengths etc.

The resistor and the diode form an AND gate. They could be replaced by a proper AND gate, but that would increase the component count. The circuit can be easily built on a piece of 16×16 stripboard, even a 11×12 piece if you connect the LCD with wires rather than a connector.

74sr-lcdAs the top circuit doesn’t really show the logical functions of the 74LS164 but merely the lay out of the chip, I added the circuit below to show its logical function:
lcd-shiftProgram:

#include <LiquidCrystal_SR.h>
LiquidCrystal_SR lcd(8,7,TWO_WIRE);
//                   | |
//                   | \-- Clock Pin
//                   \---- Data/Enable Pin

void setup(){
lcd.begin(16,2);               // initialize the lcd
lcd.home ();                   // go home
//
}
void loop(){
lcd.home ();
lcd.print("LiquidCrystal_SR");
lcd.setCursor (0, 1 );
lcd.print("2 wire");
}
LCD2Wire
Proof of concept

It is possible to let the backlight be taken care of by the software as well. Connect the circuit below to pin 4 of the SN164 and to the backlight pins of the LCD:

backlight
Backlight

The stripboard should be adapted like this:

twowirelcd_164
With backlight regulation

The full circuit like this:
lcd2wire

As I still had an old Seiko M1632 display with no back-light and a DIL 2×7 connector rather than a SIL 1×16 connector, I also quickly made a design on perfboard for that:

for Seiko M1632
for Seiko M1632

It is a 9×14 piece. If you are cramped for space you can do it on an 8×11 piece, smaller even if one uses a small standing  variable resistor. For the practical circuit I chose a slightly bigger 9×20 piece (no use trimming an already small piece), and no.. you don’t want to see the bottom side 🙂 :

m1632

As pin 4 of the 164 is used for the LCD backlight, but the Seiko doesn’t have a backlight, I decided  later to add an LED, connected through a 1 k resistor to pin 4 and be able to switch the LED on and off with the backlight command.

contrastWith regard to the potmeter for the contrast… if using a potmeter is not desirable for any reason, it is possible to set the Vlc to a voltage that is most optimal for most situations. The circuit shows how. Over the diode a voltage of about 0.65 Volt can be expected which is ideal for most situations:

8 bit Two wires

Above circuits are all for LCD in 4 bit mode as that is the most often used mode. However, Mike MacLaren pointed me to a circuit that uses a shiftregister (that link is dead, try this one) (either a 164 or a 595) that uses two wires and does full 8 bit addressing of the LCD. ( His program is for  a PIC, Check here as well)

Two Wire 8bit LCD with 164 Shiftregister
Two Wire 8bit LCD with 164 Shiftregister

The above circuit uses an HC164 shiftregister, but Mike’s site also has a circuit for a 595 and a driver program for a PIC as well as an Arduino microprocessor. This circuit does not cater for software backlight control, but it has full 8 bit control, should you need that

3-Wire LCD

LCD’s can use up quite some data lines on an arduino. Fortunately this can be reduced as most LCD’s can work in a 4 dataline mode. It can however done with even less datalines, using a shift register:

Backpack

I admit that I have been inspired by LadyAda’s ‘I2cSPI backpack’ but since I only needed the SPI mode and the pin lay-out of my LCD module was different from the LadyAda backpack. I decided to just make my own. To use this circuit one needs to install the proper LCD library.

The variable resistor can be replaced by the diode and R2. 0,65 is often the optimal voltage for the brightness. R1 and T1 are not really necessary if you do not have a backlit display (these usually come with 16 pins).

Interesting reading from Carlo Denaro can be found here. He uses  pin D10 (to 14+RS pin), D9 (to 12) and D8 (to 11)  and uses IC pin 2 for the Vlc.

More 3 wire solutions, and here

3 Wires still too many? Well, how about two wires, here too?  Some more circuits here

How about one-wire?

Identifying LCD modules

Recently I found an LCD module somewhere in one of my many boxes with things. As I had probably bought it over 20 years ago, but never used, I wasn’t quite sure anymore what the pin lay-out was.
lcd-2

Generally all these LCD modules, including this one, are based on the HD44780 chip. One could follow the lines of the SMD chip on the right of this picture and determine which pin of the connector, hooked up to which pin of the chip. Not too difficult with a small magnifying glass, but it seemed some of these tracks are under the chip, so that would be a small problem.

Now wouldn’t there be some general connection scheme? Well, yes, but there is a problem with that. There are basically two different lay-outs:

lcd3

Most of the connections between different modules are the same, but not always:

Pin Seiko M1632 Densitron LM22
1 D7 D7
2 D6 D6
3 D5 D5
4 D4 D4
5 D3 D3
6 D2 D2
7 D1 D1
8 D0 D0
9 E E
10 R/W R/W
11 RS RS
12 Vlc Vlc
13 Vss=Gnd Vdd=Vcc
14 Vdd=Vcc Vss=Gnd

As you can see, these two types differ on a very essential point: the connection for the power supply/ You do not want to mess with that. To make things even more complicated. The ‘official’ pin numbering for the Densitron is also the other way around, so what I labelled as ‘14’ is actually pin ‘1’ but for clearity’s sake I ‘normalized that in this comparison.
Also, just from looking at the LCD module you do not know what is the top or the bottom and therefore you also do not know if your connector is at the left or the right and thus you do not know what the pin numbering is to begin with, although fortunately in my case, they were numbered.

Add to that that in my LCD module some tracks were under the chip. I was going to need the datasheet of the chip:

hd44780

Compare that to my module:

lcd5

and many of the tracks can already be followed by the bare eye. It is easy to see that DB1 connects to the 4th pin on the right (which is pin 7, remember, you are looking at the back) DB0 connects to the 4th pin on the left (which is pin 8), etcetera etcetera. That all lines up with the table above. Unfortunately, the doubtful pins, the power supply pins, that should connect to the bottom 2 pins are obscure as they disappear under the chip. So, out comes the multimeter. I figured that pin 13 was the ground coz it’s track goes below the track of pin 14, which makes it very likely to connect to the Ground  pin, whereas pin 14 (if the board was designed intelligently) was much more suitable to connect to Vcc. As I hate putting multimeters on SMD pins (my eyes are not that good anymore) and it seemed the metal shield of the display was also attached to a copper track on the board, I measured between pin 13 and the metal shield/casing. Bingo! connected. With that I am pretty convinced that  this module follows the SEIKO M1632 lay-out and as a matter of fact, when looking for a picture of the SEIKO M1632  on the internet, it seemed quite similar to my module. In hindsight, the identification M1632 was even printed on the board, but almost invisible under another print: 7Y24127005
You may find datasheets  og the M1632 that give another layout of the pins. However, the following worked for me:
M1632

Now the only problem I have is that I wanted to connect it directly to a ‘Ladyada’ like ‘backpack’, but that is going to be difficult with this pin layout and I dont want to use a cable, just straight headers. Oh well, I guess I have to construct something myself then with a 595 chip.

More on these LCD’s

If you ever need to repair one, this may come in handy.

M1632 Datasheet