Sensing Humidity With The SHT15 + Arduino

Tuesday, November 27 th , 2012

The SHT15 is a digital humidity sensor that outputs a fully calibrated humidity reading. And… because what we are measuring is actually relative humidity, and relative humidity being relative to temperature, the SHT15 has a builtin digital thermometer. This makes things much easier to work with than sensors without a thermometer onboard. You can pick one up from sparkFun here.

Hooking it up

The SHT15 uses a two-wire connection for communication that is similar to, but not, I2C. So we wont be able to use the Arduino’s dedicated lines for this. The down side is it is a bit slower to get readings from, the plus side is that you can connect it to any 2 digital pins you want. We are using pins 2 and 3 on our arduino.

BEFORE YOU SOLDER IT UP… Note that this board can not be washed! So if you are using flux, or solder that you normally clean up, don’t (They actually recommend to use “no-clean” solder just so you don’t have to worry about it). And be extremely careful not to get it wet at all.

AFTER YOU SOLDER IT UP… To get a clean reading, the sensor needs to be stored at >75% humidity for at least 12 hours to allow the polymer to re-hydrate (just what the doc says). If you don’t, your SHT15 may read an offset that slowly disappears if exposed to ambient conditions. Alternatively the re-hydration process may be performed at ambient conditions (>40% Humidity) for 5 + days.

Im not exactly sure how you do that… But someone noted that they put it in a ziplock with a wet towel (not touching) for 12H.

Code

The code for this is a bit wacky (as with most digital sensors), but it is split up pretty nicely, and is as easy to read as it can be.

Note that the readings are a bit slow to return a value (100+ ms).

//Based of the wiring code at http://wiring.org.co/learning/basics/humiditytemperaturesht15.html

int SHT_clockPin = 3;  // pin used for clock
int SHT_dataPin  = 2;  // pin used for data

void setup(){
  Serial.begin(9600); // open serial at 9600 bps
}

void loop(){
  //these can take a bit to get the values (100ms or so)
  float temperature = getTemperature();
  float humidity = getHumidity();

  Serial.print(temperature);
  Serial.print(" | ");
  Serial.println(humidity);

}






float getTemperature(){
  //Return Temperature in Celsius
  SHT_sendCommand(B00000011, SHT_dataPin, SHT_clockPin);
  SHT_waitForResult(SHT_dataPin);

  int val = SHT_getData(SHT_dataPin, SHT_clockPin);
  SHT_skipCrc(SHT_dataPin, SHT_clockPin);
  return (float)val * 0.01 - 40; //convert to celsius
}

float getHumidity(){
  //Return  Relative Humidity
  SHT_sendCommand(B00000101, SHT_dataPin, SHT_clockPin);
  SHT_waitForResult(SHT_dataPin);
  int val = SHT_getData(SHT_dataPin, SHT_clockPin);
  SHT_skipCrc(SHT_dataPin, SHT_clockPin);
  return -4.0 + 0.0405 * val + -0.0000028 * val * val; 
}


void SHT_sendCommand(int command, int dataPin, int clockPin){
  // send a command to the SHTx sensor
  // transmission start
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  digitalWrite(dataPin, HIGH);
  digitalWrite(clockPin, HIGH);
  digitalWrite(dataPin, LOW);
  digitalWrite(clockPin, LOW);
  digitalWrite(clockPin, HIGH);
  digitalWrite(dataPin, HIGH);
  digitalWrite(clockPin, LOW);

  // shift out the command (the 3 MSB are address and must be 000, the last 5 bits are the command)
  shiftOut(dataPin, clockPin, MSBFIRST, command);

  // verify we get the right ACK
  digitalWrite(clockPin, HIGH);
  pinMode(dataPin, INPUT);

  if (digitalRead(dataPin)) Serial.println("ACK error 0");
  digitalWrite(clockPin, LOW);
  if (!digitalRead(dataPin)) Serial.println("ACK error 1");
}


void SHT_waitForResult(int dataPin){
  // wait for the SHTx answer
  pinMode(dataPin, INPUT);

  int ack; //acknowledgement

  //need to wait up to 2 seconds for the value
  for (int i = 0; i < 1000; ++i){
    delay(2);
    ack = digitalRead(dataPin);
    if (ack == LOW) break;
  }

  if (ack == HIGH) Serial.println("ACK error 2");
}

int SHT_getData(int dataPin, int clockPin){
  // get data from the SHTx sensor

  // get the MSB (most significant bits)
  pinMode(dataPin, INPUT);
  pinMode(clockPin, OUTPUT);
  byte MSB = shiftIn(dataPin, clockPin, MSBFIRST);

  // send the required ACK
  pinMode(dataPin, OUTPUT);
  digitalWrite(dataPin, HIGH);
  digitalWrite(dataPin, LOW);
  digitalWrite(clockPin, HIGH);
  digitalWrite(clockPin, LOW);

  // get the LSB (less significant bits)
  pinMode(dataPin, INPUT);
  byte LSB = shiftIn(dataPin, clockPin, MSBFIRST);
  return ((MSB << 8) | LSB); //combine bits
}

void SHT_skipCrc(int dataPin, int clockPin){
  // skip CRC data from the SHTx sensor
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  digitalWrite(dataPin, HIGH);
  digitalWrite(clockPin, HIGH);
  digitalWrite(clockPin, LOW);
}
Unless otherwise stated, this code is released under the MIT License – Please use, change and share it.

The Big Easy Stepper Motor Driver + Arduino

Monday, November 26 th , 2012

Stepper (or step) motors are really cool. They are perfect for automation or any time you need a motor to turn to a specific point, at a specific speed, in a specific direction. And, unlike typical motors, steppers are able to do all of this, and hold their position when they are not moving – The trade off is that they cant move as fast, and you have to power them at full power all the time, but you get total control in return.

Steppers have a minimum amount they can move known as a step. You can feel these steps if you slowly turn your stepper by hand. The most common steppers have 200 steps per revolution, so all movement is in 1.8º increments (360º / 200). Controlling them can get tricky at first, so today we are doing an article on using the Big EasyDriver Stepper Motor Driver. The big easyDriver is the big brother of the easy driver we wrote about last year. It is able to take a lot more abuse and power, so it isn’t as easy to destroy as the easy driver, can power much larger motors, and it also gives you a little more control by letting you change the microstepping setting.

Motor Voltage / Current

A lot of people ask about what voltage they should use to power their motor. Well, when using a stepper driver, you are powering the driver, not the motor. The driver will take over powering the motor for you.

It is best to power the driver with the highest voltage you can ( up to 35V max for this driver ). This will allow the motor to spin faster than if powered at a lower voltage. Exactly why this is is pretty complex, but if you want to know more about it, you should really read this: Gecko Drive – Step Motor Basics

On the bigEasy driver is a mini potentiometer to control the current to the motor. This varies between 0ma and 2A (2000ma). You want to set it to whatever your motor is rated to. Too high, and you could burn the motor up, too low, you wont get all the power out of your motor. Note: The arrow indicators on the current adjustment potentiometer are backwards. Keep this in mind when adjusting the current limits. If you are running a higher power motor, you will probably want to put a heat sink on the driver as well.

Hooking it up

Even though there are some 30 pins on the Big Easy Driver, we only need a few to get this up and running. In fact, a good deal of the pins are actually just duplicates that are spaced out differently.

The barebones setup:

Power the driver with 8-35v – If using a wall adapter, make sure the adapter has at least enough current for the motor. A higher current/amperage rating is better, and just means it wont burn out. (The Big Easy Driver can supply up to 2 amps)
Connect the 3 control wires from the “gnd”, “dir”, and “step” of the Big Easy Driver to the Arduino as shown.
Connect the stepper motor to the driver – For me the red/green were one pair, and the blue/yellow was another. If this does not work for you, see the section below on finding your motors coil pairs.

Code

For the arduino code for the driver, im going to be using AccelStepper Library. This is an amazing library that I use for all my stepper needs now. It is even does acceleration and deceleration, supports multiple drivers at once, and most importantly it is non blocking. Meaning, you can be moving your motor as you are reading from a sensor, or turning on lights etc.

The library even keeps track of the position of the motor. So if you tell it to go to 10,000 – It knows it is at 9,00 already, so it moves an additional 1000 steps. Then you can tell it to go home, and it will go back 10,000 steps to 0.

I highly recommend you download the full library from the author. The version I have here is barebones with none of the examples. It is just here because I believe if you post code, you should post everything you need to make it work

To make this code work, before you load the code, or even open the Arduino program, we need to place the “AccelStepper” folder into your Arduino Library. If you don’t know where that is by default, Look to the right.
If you click the download button to the right of “Arduino” you can download the whole thing as a zip, so you dont need to copy all the files.

Default Library Folder Location

On your Mac:: In (home directory)/Documents/Arduino/libraries
On your PC:: My Documents -> Arduino -> libraries
On your Linux box:: (home directory)/sketchbook/libraries

Additional Information

Finding Your Motors Coil Pairs

This driver only needs 4 wires from your stepper. If you have a 4 wire stepper, awesome! If you have a 6 wire stepper, it will be slightly trickier. But no matter what, we need to find the 2 main coils inside of the motor. And if you get it wrong, the motor will just twitch or not move, but you wont break it.

4 wire motor

Using an ohmMeter, pick one wire at random, and test it with the others until you find a pair that shows resistance of a few ohms (1 – 200ohms most often). Those 2 are your “pair A”. Make sure the other 2 wires have the same resistance on them, (if not, it may be broken) and that is your “pair B”. With the two pairs of wires, there isnt a backwards, so just plug wires from “pair A” into the “A” on the driver, and “pair B” into “B”.

6 wire motor

Checking the documents on the motor is the easiest, but if you dont have it, read on.

6 wire motors have two coils in them just like 4 wire motors. But 6 wire motors also have extra wires that connects to the middle of each coil (centers). So each coil actually has 3 wires, a center and two ends. We don’t use coil center wires, we just need the 4 coil ends (2 from each coil).

Basically, We need to find ends of the two coils. The ends of the coils will have twice the resistance as the center to an end. So we need two pairs of wire that have the highest resistance in the group.

The easiest way to find out the right 4 wires is to look at the documentation for the motor, but if you dont have that, you can with some testing, find the right ones.

To find the correct 2 wires, we need to locate the 3 wires from each coil. Start by just picking one at random, and using an ohmMeter, test the resistance with the others until you find the 2 connected to that wire. (3 of them will show no connection because they are part of the other coil). Now, these 3 are for coil “A”. Now, take these 3 wires and test the resistance between any 2 of them until find the 2 that have the highest resistance. These are the two ends of that coil “A”. Do the same for the other 3 wires to locate the ends of coil “B”.

With the two pairs of wires, there isnt a backwards. So just plug wires from coil A into the A on the driver, and the two from coil B into b.

8 wire motor

There is no way to do this without looking at the documentation.

Microstepping

Most stepper drivers offer something called microstepping, and the Big Easy Driver is no exception. As I mentioned before, steppers have that minimum movement called a step. Microstepping breaks down that step into smaller micro steps. Microstepping allows for smoother, quieter, more accurate control, at slower speeds.

When using microstepping, a step motor will require more “step pluses” to move the motor. For instance if you are using 16 microsteps (the default on the Big Easy Driver) per step, a 200 step motor would require 3200 “step pluses” to make a full revolution. Just take note when you wonder why telling it to step 200 steps barely rotates the motor.

Microstepping will reduce the maximum speed / torque of the motor (about 30% less), so it is a trade of speed vs smooth. Because of this, many high end drivers switch to full stepping (no microstepping) at higher speeds, and technically, you could do that with the big easyDriver, but it’s too complex for me to figure out, so I wont be covering that.

Adjusting the microstepping

The Big Easy Driver defaults to 16 step microstepping mode. If you want to reduce that, you can do so by pulling the MS1, MS2, and MS3 pins HIGH (connecting them to 5V) or LOW (connecting them to GND). Check out the chart on the side to see how make the adjustments.

Touch Sliders With A Softpot + Arduino

Monday, November 26 th , 2012

You all know the potentiometer, you turn it, and you can read on your arduino where it was turned to. Well 3M makes a product called the softpot that is a linear touch potentiometer. So instead of turning a knob, you touch it.

The really nice thing about these is that they are great for prototypes because you can tell where someone touched it. So if you place a piece of paper with some printed buttons over it, you can mock up surface touch buttons. Or if you need to prototype a rotary touch wheel like the old ipods, but don’t want to get involved with complex capitative sensors, you can do that too.

There are a million uses for these, and they come in a few sizes, shapes, and even offer high temperature versions.

Hooking it up

The softpot sensors change their resistance depending on where they are touched. And because they work just like potentiometers you don’t need any extra parts to use them with your arduino. We can just plug in the middle pin to an analog in pin on the arduino and we are ready to go.

The arduino analogRead will vary between 0 and 1023 depending on where you touch it, (1023 when not being touched) and is linear, so it will be about 512 if touched in the middle.

WARNING!!!!!

If you touch the softpot at the top and the bottom at the same time, it will get really hot, really quick, and if you leave it for more than a second, you may burn it up. I have no clue why. But beware!

This is especially an issue on the round version. If you press down dead center on the bottom (where the straight parts come off of), you will be pressing on both sides of the pot and it will again get super hot and melt. SO DONT PRESS IT IN THE MIDDLE BOTTOM

Code

The arduino code for this just could not be easier. We are adding some serial prints and delays to it just so you can easily see the readings, but they dont need to be there if you dont need them.

int softpotPin = A0; //analog pin 0

void setup(){
  digitalWrite(softpotPin, HIGH); //enable pullup resistor
  Serial.begin(9600);
}

void loop(){
  int softpotReading = analogRead(softpotPin); 

  Serial.println(softpotReading);
  delay(250); //just here to slow down the output for easier reading
}
Unless otherwise stated, this code is released under the MIT License – Please use, change and share it.

« Older Entries