Notes About Working with Various Arduino & Netduino Microcontroller Boards

Monday, October 29, 2012

Using the HIH-4030 with an Arduino Uno to Measure Relative Humidity

To use the HIH-4030, you also need to measure the current temperature. To test the HIH-4030, I am using the DHT22 to measure temperature and humidity and the same board to provide a comparison. 

The data line (HIH-4030 center pin) is connected to Arduino analog pin 1.

Use code like this in the loop() to print the reading to the serial console:

 float v = analogRead(1);
 float tmp = DHT22.celcius();
 float RH = ((((v / 1023) * 5) - 0.958) / 0.0307) / (1.0546 - 0.00216 * tmp);
 Serial.print("HIH4030 RH%: ");
 Serial.print(RH);
 Serial.println("% ");


 The value returned by this code is within 2% of the RH% returned by the DHT22.

Friday, October 26, 2012

Using the 4x4 Universal 16 Key Keypad for Arduino

The listings at Amazon and other online vendors show this inexpensive membrane keypad as "4x4 Universial 16 Key Switch Keypad Keyboard For Arduino." There was no documentation for the product, nor were there any links from Amazon. Here are my notes on how to connect and test this keypad.

The arrangement of the keys is

1 2 3 A 
4 5 6 B 
7 8 9 C 
* 0 # D

There is a ribbon with 8 wires running from the bottom of the keypad. With the keypad face up, the wires connect in sequence from left to right to Arduino digital pins 2 - 9. Don't use digital pins 0 and 1 on the Arduino Uno, since they are used for serial communication.

The Arduino Keypad library is available from the Arduino Playground.

Note: I also have an I2C version of this example (01/24/13).

Note: I have posted a C/Linux example of using this keypad with an Arduino Galileo (running at the Galileo's command line rather than as an Arduino sketch). (06/04/2015)

 The following code will allow you to test the keypad. As each key is pressed, the corresponding character should appear on a separate line in the Arduino IDE's serial console.


#include <Keypad.h>

const byte ROWS = 4; 
const byte COLS = 4; 
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {2,3,4,5}; //connect to row pinouts 
byte colPins[COLS] = {6,7,8,9}; //connect to column pinouts

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

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

void loop(){
  char key = keypad.getKey();

  if (key != NO_KEY){
    Serial.println(key);
  }
}

SainSmart IIC/I2C/TWI Serial 2004 20x4 LCD Module Shield

SainSmart IIC/I2C/TWI Serial 2004 20x4 LCD Module Shield is much easier to use than simpler LCD displays. Here's an I2C example.  It requires only 4 wires: 5 v, GND, SCL, and SDA.  For the Arduino Uno, connect SDA to A4 and SCL to A5.  (On the Leonardo: SDA = D2, SCL = D3 ).

The LiquidCrystal_I2C library for the 20 x 4 display is available from www.yourduino.com. For documentation, see this page.

Here's a very simple example:


#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

//Addr: 0x3F, 20 chars & 4 lines
LiquidCrystal_I2C lcd(0x3F,20,4); 

void setup()
{
    lcd.init(); 
    lcd.backlight();
    lcd.setCursor(0, 0);
    lcd.print("Hello");
}
void loop()
{

}

I had found that the I2C address is 0x3F, not 0x27 as shown in some of the online examples. As noted in the comments below, though, it seems that some units have the 0x27 address indicated in the documentation. You may need to try both addresses.   

Note (12/14/2013):  I have had occasion to use this display with the Arduino Due and the 3.3V Sparkfun Arduino Pro Mini 328.  It works with both (with VCC on the display connected to 3.3V).  In both cases I've used Arduino IDE ver. 1.5.4.

Sunday, October 21, 2012

Using an LCD Display with the Arduino WiFi Shield

The Arduino LiquidCrystal library makes it easy to use an LCD display. (For tutorials and ample code see the Arduino LiquidCrystal page or the Adafruit Learning Systems page). 

The Arduino WiFi shield is an easy but rather pricey (circa $85.00 US) way to connect an Arduino to a wireless network. I find the Arduino WiFi shield easier to use than the LinkSprite Cuhead WiFi Shield V2.0 (but the LinkSprite does work and costs about $30.00 less).

I have created a very simple application with an Arduino Leonardo that uses a TMP36 temperature sensor and displays the temperature on a Web page (using Web server code taken from the WiFiWebServer example contained in the Arduino WiFi library.) The LCD displays the IP address used by the shield and the last temperature reading. My wireless network is encrypted using WPA.

The only real challenge is getting the digital pin connections for the LCD right, since digital pins 4, 7, 10, 11, 12, and 13 are used by the WiFi shield. The code below assumes the following connections between the Arduino and the display. Only differences from the connections in the LCD tutorials above are noted here.

  • LCD4    -->  D8
  • LCD8    -->  D9
  • LCD11   -->  D6
  • LCD12   -->  D5
  • LCD13   -->  D3
  • LCD14   -->  D2
The data line for the TMP36 is connected to the Arduino's Analog 0 pin.

Here's the sketch code:

#include <LiquidCrystal.h>
#include <WiFi.h>
#include <WiFiServer.h>
#include <SPI.h>


char ssid[] = "NETWORL_NAME_HERE"; 
char pass[] = "WPA_PASSWORD_HERE";
int keyIndex = 0;     

int status = WL_IDLE_STATUS;
WiFiServer server(80);
LiquidCrystal lcd(8, 9, 6, 5, 3, 2);

void setup() {
  lcd.begin(16,2);  
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) { 
    // don't continue:
    while(true);
  } 
  
  // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED) { 
    status = WiFi.begin(ssid, pass);
    // wait 5 seconds for connection:
    delay(5000);
  } 
  server.begin();
  lcd.setCursor(0, 0);
  IPAddress ip = WiFi.localIP();
  lcd.print(ip);
}

void loop() {
  // listen for incoming clients
  WiFiClient client = server.available();
  if (client) {
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        // if you've received a newline character & the line
        // is blank, http request has ended, so you can send 
        // a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connnection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          // add a meta refresh tag, so the browser pulls again
          // every 60 seconds:
          client.println("<meta http-equiv=\"refresh\" content=\"60\">");
          float temp = getTempF();
          client.println(temp);
          lcd.setCursor(0, 1);
          lcd.print(temp);
          client.println("</html>");
           break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(3);
    // close the connection:
    client.stop();
  }
}

float getTempF() {
  float t = (analogRead(0) * 0.004882814 - 0.5) * 100; 
  return t * 9 / 5 + 32;
}