Friday, August 19, 2016

43: Linear Motors -- Arduino
revised 8/26/16

I got a stepper working after I bought one with the control interface card. But for my "Dog Treat" system I decided that a linear motor would be most reliable for spitting out dog treats. I bought 2. Here's #1:


#2:

                        top of #2                   under side     control board
                                                        of  #2             for 28B...

Right away, problems. My 28BYJ-40 stepper has 5 wires to the little board. My linear #1 only has 4 wires (blue, yellow,black, red). Will the little interface work? How do I wire it? Ditto for #2 (after I figure out how to solder the tiny contacts).

REVISION:
To get motor #1 to work I bought an "Easy Driver" through Amazon. After the nasty soldering and a couple wrong-headed examples from Googling "arduino stepper..." I got "SparkFun Easy Driver Basic Demo" code & wiring to work.

Motor #2: Soldering to those tiny contacts? First off, I shorted 2 and had to de-solder & start over. Then the same code & Easy Driver worked -- except -- forward and backward are reversed (but then the contacts weren't labeled). Also, #2 spiral gear is "coarser" so a small motor rotation moves much farther. Actually (ignoring soldering), I like #2 better -- the 2 screws will make it easier to connect to something useful.

Also: what's the best way to avoid running the plastic piece past the end of the screw? 

Wednesday, August 10, 2016

42: DHT22 Update of Post 39

Well, my sensor inside a cut-off water bottle failed after a couple days. So I put the next try inside a opaque plastic box that is sealed except for 2 screen-covered 1" holes. But the thing that makes it work (I think) is the tiny fan that blows directly on the DHT22. It still stops working briefly when the humidity reaches 100% but it then recovers after an hour or so. To make this work I had to increase the 5v power to the Photon to 2.4 amps.

I also tried the HIH-4030 sensor in the same environment. Guess what: it stops working at 100% RH, too.

Sunday, June 5, 2016

41: Stepper Motors

I have a mad urge to build an interactive amusement for the left-at-home dogs in my extended family. Yeah, I know other people have-done/are-doing this. So what. Details at http://dicks-raspberry-pi.blogspot.com/, post 99.

Anyway, one feature has to be the ability of the device to spit out doggie treats. I expect the main computer for this will be a Raspberry Pi. And I started stepper programming in Python on the Pi but realized quickly that precise timing is a problem again. Mostly because I want to be able to calibrate the motor position using a photo sensor. Reading such a sensor on the non-analog Pi is slow. So I'll add an Arduino for the motor and the photo sensor chore.

Stepper 28BYJ-48 5V DC + ULN2003 Driver Board
-- don't buy without the driver board --
(otherwise the wiring will drive you nuts)

Here's some C++ I'm currently using (9th try from downloaded sources, I forget which):

int motorPin1 = 8;    // Blue   - 28BYJ48 pin 1
int motorPin2 = 9;    // Pink   - 28BYJ48 pin 2
int motorPin3 = 10;    // Yellow - 28BYJ48 pin 3
int motorPin4 = 11;    // Orange - 28BYJ48 pin 4
                       // Red    - 28BYJ48 pin 5 (VCC), not used
int bits[8] = {B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};

int photo = A5;

void setup() {
  //declare the motor pins as outputs
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);
  Serial.begin(9600);
  pinMode(photo, INPUT);
}

char ch;

void loop() {
  // wait for any typed character
  if(!Serial.available()) return;
  ch = Serial.read();
  spr(ch);
  clockwise(128); // not exactly 1 rotation
  delay(1000);
  anticlockwise(128);
  delay(1000);
}

void clockwise(int n) {
  for(int j = 0; j < n; ++j) {
    for(int i = 7; i >= 0; i--) {
      setOutput(i);
      delay(2);
    }
  }
}

void anticlockwise(int n) {
  for(int j = 0; j < n; ++j) {
    for(int i = 0; i < 8; i++) {
      setOutput(i);
      // read photo pin & stop on overrun
      delay(2);
    }
  }
}
void setOutput(int out)
{
  digitalWrite(motorPin1, bitRead(bits[out], 0));
  digitalWrite(motorPin2, bitRead(bits[out], 1));
  digitalWrite(motorPin3, bitRead(bits[out], 2));
  digitalWrite(motorPin4, bitRead(bits[out], 3));
}
==============
To be added to Arduino code: serial command from the Pi.

Question: anyone know how to change the steps per rotation?

Saturday, May 21, 2016

40: C++ map() function vs. the HIH-4030 Humidity Sensor
-- revised 5/22/2016 --
-- re-revised5/25/2016 --

So I got my expensive HIH sensor (explained in post 39).

tiny, isn't it

According to Honeywell's graph there is a straight line relationship between voltage output (at 5v, 20C) and relative humidity. I.e., 0.8v = 0% to 3.75v = 100%.

So I wrote this Arduino sketch:
=============
#define spr(x) Serial.print(x)   // because I'm a slow typist
#define spl(x) Serial.println(x) //      " "

void setup() {

  pinMode(A1, INPUT);
  Serial.begin(9600);
  delay(5000);
  spl("HIH-4030");
}

void loop() {

  int r = analogRead(A1);
  spr("raw: ");spr(r);
  float v = r * (5.0 / 1023.0);
  spr(", V: ");spr(v); 
  float rh = map(v, 0.8,3.75, 0.01,100.0);
  spr(", rh%: ");spl(rh);
  delay(5000);

============
This produced the following output (from Mac Coolterm):
============
raw: 297, V: 1.45, rh%: 33.00
raw: 305, V: 1.49, rh%: 33.00
raw: 289, V: 1.41, rh%: 33.00
raw: 224, V: 1.09, rh%: 33.00
raw: 651, V: 3.18, rh%: 100.00 *
raw: 526, V: 2.57, rh%: 66.00
raw: 367, V: 1.79, rh%: 33.00
raw: 322, V: 1.57, rh%: 33.00
raw: 291, V: 1.42, rh%: 33.00
raw: 278, V: 1.36, rh%: 33.00
============ * I breathed on the sensor
The "33", "66", etc.  made me suspect that while the C++ map() function happily accepts float arguments, it treats them as integers. So I wrote my own float version:
============
#define spr(x) Serial.print(x)
#define spl(x) Serial.println(x)

float mapf(float value, float istart, float istop, float ostart, float ostop) {

    return ostart + (ostop - ostart) * ((value - istart) / (istop - istart));
}
void setup() {
  pinMode(A1, INPUT);
  Serial.begin(9600);
  delay(5000);
  spl("HIH-4030");
}

void loop() {

  int r = analogRead(A1);
  spr("raw: ");spr(r);
  float v = r * (5.0 / 1023.0);
  spr(", V: ");spr(v); 
  float rh = mapf(v, 0.8,3.75, 0.0,100.0);
  spr(", rh%: ");spl(int(rh));
  delay(5000);
}
============
Here's the "mapf()" output:
============
raw: 295, V: 1.44, rh%: 25
raw: 294, V: 1.44, rh%: 24
raw: 293, V: 1.43, rh%: 24
raw: 318, V: 1.55, rh%: 29
raw: 449, V: 2.19, rh%: 52 *
raw: 378, V: 1.85, rh%: 39
raw: 306, V: 1.50, rh%: 27
raw: 293, V: 1.43, rh%: 24
raw: 291, V: 1.42, rh%: 24
============ * hot breath, again
Nasty! I wonder whether the provided map() code protects against divide-by-zero? It could happen.

Now I just have to worry about why my HIH-4030 values are screwy -- readings around my house are in the 40s, at the moment.

Later: Then I moved the program to the Particle Photon. The only source change was for the 12-bit analog return (4095 instead of 1023). The Particle C++ map() function bug ("feature") was the same. But, for some reason the results were correct!
============ code:
#define spr(x) Serial.print(x)
#define spl(x) Serial.println(x)
// sensor to Photon: 5v to Vin, 0v to A1, GND to GND

float mapf(float value, float istart, float istop, float ostart, float ostop) {

    return ostart + (ostop-ostart) * ((value-istart) / (istop-istart));
}

void setup() {
  pinMode(A1, INPUT);
  Serial.begin(9600);
  delay(5000);
  spl("HIH-4030");
}

void loop() {

  int r = analogRead(A1);
  spr("raw: ");spr(r);
  float v = r * (5.0 / 4095.0);
  spr(", V: ");spr(v); 
  float rh = mapf(v, 0.8,3.75, 0.0,100.0);
  spr(", rh%: ");spl(int(rh));
  delay(5000);
}
============ ok results?
rawh: 1674, V: 2.04, rh%: 42
rawh: 1576, V: 1.92, rh%: 38
rawh: 1607, V: 1.96, rh%: 39
rawh: 1562, V: 1.91, rh%: 37
============
Finally, about the HIH readings: they vary a lot between samples so my latest code reports a weighted running average -- 3 previous readings and the latest one doubled.

Revision: I soldered the tiny board to wires -- trying to keep from frying it in the process. I found new software on Github. Now the Arduino is right (seemingly) and the Photon is too high*. The HIH-4030 is a pain. The mounting board should be bigger just to protect the sensor part.

* Because the Photon analog pins are only rated for 3.3v. It's in their Docs -- but not obvious. Forget my code. Use the more accurate code from github.

Sunday, May 15, 2016

39: Problems with DHT22 Temperature/Humidity Sensors

For the past month or so I've tried DHT22s in my granddaughter's hoop house. With them I can provide her with useful humidity and dew point data. As I've mentioned in an earlier post, the hoop house is a rather hostile environment for electronics. If the spring sun is out, the temperature/humidity mid-day can be 90F/25% and at 2AM 40F/99% (dew point 40F). I've tried three different DHT22s and they have all failed after a few nights of 99% humidity. For my latest attempt I housed the DHT inside 16oz water bottle (bottom cut off, sealed at the top). It lasted 2 nights. BTW: they recover after a couple days away from the hoop.

Now I've ordered an HIH-4030, humidity-only sensor (much more expensive). I'll pair it with a cheap TMP36 (cheap & reliable). Unlike the DHT22, the HIH provides a simple analog output.  I won't have to use a mysterious software library -- but I'll have to run 2 sets of wires instead of 1.

Anyone have similar problems?

Wednesday, May 4, 2016

38: Particle Electron -- Bah, Humbug.
-- see post 36 --

After waiting months, breaking the first one and wasting 30 hours trying to get the 2nd one to work reliably, I've given up on the Electron. It seems clear to me that a cheap cell modem & cheap month-to-month service connected to Particle Photons is cheaper and much more reliable. Too bad I didn't figure that out before I blew $150 plus hours of effort!

Saturday, April 23, 2016

38: Search for the Perfect Connector

Here's some recent purchases:


The white spring clips are cheap, easy to use, fairly secure, not waterproof. I've had some of the 2-wire type for a year. They are useful while you are messing around. Generally better than alligator clips.

The lower set are pretty much the opposite: secure, waterproof and not cheap. And once you snap one of these suckers together it's work getting them apart. But really waterproof. Also, they could use a screw-down hole like the white clips.

The search goes on...