perkee's blog

I heard you like science. tags
Mar 04
Permalink

Programming for Space Efficiency

When we last left off with the physical Gmail notifier, we were using pin #11 for PWM output proportional to the number of unread emails. We were using pin #13 (which on my Duemilanove has a built in LED) for binary output of whether or not there were unread emails.

The problem I have with that is that I am a cheap bastard. And even though I get a lot of parts for free from the shop at school, I always feel like an asshole, becuase I’m going there hat in hand, and I don’t think a lot of people do that. How does that affect this? Headers. I don’t want to stick bare wire into the arduino sockets if I can help it, because it always feels so flimsy. Headers have the satisfying connection feel of an original gameboy cartridge. And as I have it now, I am using the closest possible output PWM enabled pin to the ground, so I am minimizing the number of used headers. But I can minimize even more if I set some neighbor to pin #11 to ground, so that I only need two headers to do PWM output, or 2 headers to do binary output (to an external LED), or three headers to do both. A word of caution if you do both, however: put a diode on any ammeter on the PWM side. Otherwise, when the duty cycle goes low you will be putting power through it backwards, which may have adverse results.

I added this line to the top of the program, before the setup()

const int gndPin = 12;

I added these line to setup()

pinMode(gndPin, OUTPUT);
digitalWrite(gndPin, LOW);

And that was it. However, I found that I immediately started having problems. I put some debugging lines into the Python script and the Arduino program. What I discovered was that, fr some unknow reason, no matter what I transmitted to the Arduino over serial (including from within the Python console), the Arduino mapped that number to 231. Weird. I thought there might be somehting wrong with the way the Arduino was handling the math it had to do to the byte it received over serial. I decided to play things a little safer, and expand one operation into two lines. I went from this:

val = map(constrain(Serial.read(),0,maxEmail),0,maxEmail,0,255);
analogWrite(fadePin, val);

to this:

val = Serial.read();
    Serial.print("Val raw:");
    Serial.println(val, DEC);
    val = map(constrain(val,0,maxEmail),0,maxEmail,0,255);//I rarely have more than 10 unread emails
    // set the brightness of the LED
    analogWrite(fadePin, val);
    Serial.print("Val new:");
    Serial.println(val, DEC);

That seemed to do the trick. I really don’t quite get it, and it bugs me that I don’t.

This is how I sent particular bytes over serial using the Python console. There may be other ways to do it, but since I want to limit the variables affecting the operation, I decided to go this way. For reference, I am starting from the command line in any folder, it doesn’t really matter where. You need the pySerial library. Python installation is a snap, the documentation is on the SourceForge page for pySerial. As always, change my serial port name to yours, and my speed to your prefered one as well.

$ python
Python 2.3.5 (#1, Jan 12 2009, 14:13:25) 
[GCC 4.0.1 (Apple Computer, Inc. build 5363) (+4864187)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import serial
>>> ser = serial.Serial("/dev/tty.usbserial-A6006hmD",115200)
>>> ser.write("\x01")
>>> ser.write("\x04")
>>> import sys
>>> sys.exit()
$

Here is the full source of my program. As yet, I don’t I’ve yet solved the problem whereby I have to keep the serial monitor open.

/*
 *Scaled Dimmer by Perkee/Perko
 *Check out http://perkee.tumblr.com
 *
 *
 * Dimmer
 * by David A. Mellis
 *
 *
 * Demonstrates the sending data from the computer to the Arduino board,
 * in this case to control the brightness of an LED.  The data is sent
 * in individual bytes, each of which ranges from 0 to 255.  Arduino
 * reads these bytes and uses them to set the brightness of the LED.
 *
 * http://www.arduino.cc/en/Tutorial/Dimmer
 */
 
const int fadePin = 11;
const int binaryPin = 13;
const int maxEmail = 10;//No matter what, the email will be on a scale, so this helps
const int gndPin = 12;
byte val;
void setup()
{
  // begin the serial communication
  Serial.begin(115200);
  pinMode(fadePin, OUTPUT);
  pinMode(binaryPin, OUTPUT);
  pinMode(gndPin, OUTPUT);
  digitalWrite(gndPin, LOW);
  val = 0;
}
void loop()
{
  // check if data has been sent from the computer
  if(Serial.available() > 0)
  {
    // read the most recent byte (which will be from 0 to 255)
    val = Serial.read();
    Serial.print("Val raw:");
    Serial.println(val, DEC);
    val = map(constrain(val,0,maxEmail),0,maxEmail,0,255);//I rarely have more than 10 unread emails
    // set the brightness of the LED
    analogWrite(fadePin, val);
    Serial.print("Val new:");
    Serial.println(val, DEC);
    if (val > 0)
    {
      digitalWrite(binaryPin, HIGH);
    }else{
      digitalWrite(binaryPin, LOW);
    }
    delay(1000);
  }
}
Comments (View)
blog comments powered by Disqus