Saturday, February 28, 2015

4: More on Gas Sensors
* revised 3/2/15 *

Things I've learned since last post:
  1. The timing for letting the sensor heat up in my last post is wrong. I did 50 tries waiting 4 seconds between each. 50 is ok but 5 second wait is better.
  2. The usual web examples suggest that the 5v to heat up the sensor needs too much current for it to come from the Arduino 5v pin. So I tested both my MQ-4 and MQ-7 both ways -- with external source and from the 5v pin. Both ways worked with the following caveat: the base (heated up) values were higher (both MQs) with Arduino juice (30%-ish). So why bother with external? Wrong again! Seemingly any change on the current load on the Arduino's pins changes the warm-up and base readings from the MQs. Back to external 5v (Drat!).
I want to mount my project as a hand-held portable unit like the diagram below. But I'll need to do 2 things to make this work: a) put a switch on the 5v lines to the MQs (so as not draw both currents at once) and b) de-solder the actual sensors from their circuit boards so I can mount them as shown.


the size of a flashlight
Comments?

Wednesday, February 18, 2015

3: Gas Sensors

I purchased 2: an MQ-4 (methane) and MQ-7 (carbon monoxide/CO). I shopped around for wiring and code examples and then reworked it for my sensibilities.

The MQ-x's need to heat up before their readings stabilize so I chose to power them separately from the Nano. I stripped one end of a USB cable and soldered a jumper to the red and black wires (i.e., 5v & ground). The wiring is simple. There are 4 pins on my devices, labeled G, AO, DO & V.

Wiring:
  USB 5v to V
  USB ground to G
  Arduino pin A0 to AO

— the adjustment screw didn't seem to do much —


And here's a sketch:

// Works with MQ-4/methane & MQ-7/CO
// Power to sensor external (USB) 5v->V pin & GND->G pin; 
// AO pin to Arduino A0
const int LedPin = 6;
const int gasSensor = A0;
int sensorValue;
int baseValue;

void setup() {
  int i, val, last=-1;
  pinMode(LedPin, OUTPUT);
  Serial.begin(9600);
  // wait for sensor to warm up -- and value to stabilize
  for(i = 0; i < 50; ++i) { // a guess about waiting
    val = analogRead(gasSensor);
    // Debug only
    Serial.print(i);Serial.print(","); Serial.println(val);
    if(val == last) break;
    // blink LED to indicate sensor warm up
    digitalWrite(LedPin, HIGH);
    delay(100);
    digitalWrite(LedPin, LOW);
    delay(4000); // 4 seconds
    last = val;
  }
  baseValue = val + 10; // just a guess
}

void loop() {
  sensorValue = analogRead(gasSensor);
  Serial.println(sensorValue); // Debug
  if (sensorValue > baseValue) {
    digitalWrite(LedPin, HIGH); // I need to show multiple levels
  } else {
    digitalWrite(LedPin, LOW);
  }
  delay(1000);
}

I've also successfully (seemingly) programmed an RFID reader. My sensor came with 2 testing samples: a keyfob and a credit card. I copied different sketches from the Internet and nothing worked. It turned out that my code wasn't at fault. I just tested using the fob. When I finally tried the card my sketch worked. Bad fob! There is a lesson here somewhere.

Monday, February 16, 2015

2: How the Arduino "Sketch" Works (maybe)

For C or C++ programmers the hidden code behind the sketch probably works (or can be visualized) like this:

void main() {
setup();

while(1) {
    loop();
}

Of course this doesn't explain other stuff you can add -- like this:

//optional #include statements
//optional #define statements
//optional variable declarations

setup() {
//whatever
}

loop() {
//main code -- an exit() just reexecutes loop()
}

//optional user-written functions


Saturday, February 7, 2015

Post 1: The Reluctant Arduino Programmer

I sort of backed into Arduino. In April 2013, I got my first Raspberry Pi Model B. Since then I have spent a few hundred hours (many frustrating) learning about programming sensors on the Pi. See my other blog--


--where, even there, I wandered into the forest of Arduino (posts 54, 66 - 68, 70). Even though a 32k/16mhz Arduino has 1/30th (?) of the power of a Pi B+ (1/100th of a 2B?) and you have Linux, and can program in Python and Bash and have the services of Crontab -- even so there are things that are better done on a no-OS Arduino in C++. These include:
  1. Getting accurate readings from devices that have to be read in "real time."
  2. Analog is built in and easy to program (why not on the latest Pi?). Also PWM.
  3. What if you want to build something that fits in your hand and runs on a 9v battery?
  4. Also, it's easy to use Arduinos as Pi front-ends. You can extend sensors 16' with USB or a few hundred feet wirelessly with cheap RF.
  5. The program memory on an Arduino is not lost when power is removed. It's flash memory -- like flash drives. If you download a program now (called a "sketch") it will run again a year from now when you supply power. So you program and debug using USB from Mac/PC/Linux then disconnect. When you connect a battery you're back in business.

I probably should mention the programming side of this. While my only formal training in electricity was 10th grade Physics, I have been programming since 1961. And I was at Bell Labs when Unix and C language were invented. I've written thousands of lines of C over the years. No biggie.
Arduino Micro & Nano Models
plug directly into a breadboard!

Disclaimer: I've never had a regular Arduino Uno. I've had a Micro model from Adafruit (official unit with the infinity symbol, $25). And I've had several clones (does anyone know how many of these have been built?). I've paid anywhere from $17 down to $3 for the clones. The Micro and the 2 $3 ones "don't work." 

Don't you hate it when some friend tells you their computer "doesn't work." To be specific: the problem is that when I plug them in to a USB port on my Mac no device appears in the /dev (device) list. I think you'd find it hard to find this documented, but apparently every Arduino is supposed to have a unique device ID number burned in somewhere. Anyway, if the Mac can't find the device then it can't download code or get output back. The Arduino may be working but it's useless.

Here's the idea that got me into the Arduino--

My ill-conceived "E-Cane"

My electronic cane for the vision-impaired was a learning experience but it only worked part time -- and part time isn't close to good enough. Here's some reasons that my device didn't work:

  • I tried 5 different rangefinder devices and none of them were good enough. I finally settled on a Sharp active IR unit but it is not accurate enough (especially held at an angle) and has too wide a field. I think that for big bucks the right sort of device could be built -- but not with my budget.
  • The Arduino is billed as a "programmable controller" (not a "computer"). I learned that is too true. The first thing I programmed was the accelerometer (so I could tell what angle the user was holding the e-cane). But it turns out that the Arduino's 16mhz processor is too slow to read the rangefinder and the accelerometer in a reasonable length of time. So I dumped the accelerometer.
  • The vibrators I got from Adafruit turned out to be kind of feeble (stronger ones are called "cell phone vibrators). Another problem arises from the fact that the vibrators are really tiny electric motors with off balance rotors. I thought I could spin the devices for 100ms and 500ms and that a user could tell the difference. Not so. Once you start them spinning they stop when they feel like it. Later, I realized that I could use PWM (pulse width modulation) to make the vibrators communicate better.
New topic: I recently got something called a "Terminal Adapter" (for the Nano) from Aliexpress. It was a lot of soldering (60 wires) but it works great; no breadboard needed for simple wirings and device wires are screwed down tight.
Here's a minimal test setup

And here's the sketch:
int LedPin = 6; // a digital + PWM pin
int ct = 0;

void setup() {
  pinMode(LedPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  if(ct >= 250) ct = 0;
  ct += 10;
  Serial.println(ct);
  analogWrite(LedPin, ct); // vary brightness with PWM
  delay(200);
}