byte lightLevel = 0;
float temperatureCentigrade = 0;
float temperatureFahrenheit = 0;
unsigned long then = 0;
static const int lightAnalog = 4, lightDigital = A4;
static const int temperatureAnalog = 5, temperatureDigital = A5;
static const int oversample = 10;
static const float reference = 4.66; // Measured; nominally 5v, or 3.3v external.
static const boolean internal = true;
void sense(unsigned long now) {
int lightRaw = 0;
for (int ii = 0; ii < oversample; ++ii) {
lightRaw += analogRead(lightAnalog);
delay(1);
}
lightRaw /= oversample;
int temperatureRaw = 0;
for (int ii = 0; ii < oversample; ++ii) {
temperatureRaw += analogRead(temperatureAnalog);
delay(1);
}
temperatureRaw /= oversample;
float lightVolts = (lightRaw * reference) / 1023.0;
lightLevel = 100 - ((100UL * lightRaw) / 1023);
float temperatureVolts = (temperatureRaw * reference) / 1023.0;
temperatureCentigrade = (temperatureVolts - 0.5) * 100.0;
temperatureFahrenheit = (temperatureCentigrade * 1.8) + 32.0;
Serial.print(lightRaw);
Serial.print('=');
Serial.print(lightVolts);
Serial.print('v');
Serial.print('=');
Serial.print(lightLevel);
Serial.print('%');
Serial.print(' ');
Serial.print(temperatureRaw);
Serial.print('=');
Serial.print(temperatureVolts);
Serial.print('v');
Serial.print('=');
Serial.print(temperatureCentigrade);
Serial.print('C');
Serial.print('=');
Serial.print(temperatureFahrenheit);
Serial.println('F');
then = now;
}
void sense() {
sense(millis());
}
void setup() {
Serial.begin(9600);
pinMode(lightDigital, INPUT);
digitalWrite(lightDigital, LOW);
pinMode(temperatureDigital, INPUT);
digitalWrite(temperatureDigital, LOW);
if (!internal) {
analogReference(EXTERNAL);
delay(1);
}
sense();
}
void loop() {
unsigned long now = millis();
if ((now - then) > 1000) {
sense(now);
}
}
Friday, January 27, 2012
Wireless Remote Sensing with Arduino and Zigbee
Thursday, January 26, 2012
Another Tragic Victim of Electrostatic Discharge
If Chip spends more than a day trying to solve a software problem, it's a hardware problem. -- Mrs. Overclock's Law
Tuesday, January 24, 2012
Remote Sensing with Arduino
#include <SPI.h>
#include <Dhcp.h>
#include <Dns.h>
#include <Ethernet.h>
#include <EthernetClient.h>
#include <EthernetServer.h>
#include <EthernetUdp.h>
#include <WebServer.h>
#include <util.h>
#include <avr/pgmspace.h>
byte lightLevel = 0;
float temperatureCentigrade = 0;
float temperatureFarenheit = 0;
unsigned long then = 0;
void getIndexHtml(WebServer & server, WebServer::ConnectionType type, char * urlTail, bool tailComplete) {
server.httpSuccess();
if (type == WebServer::HEAD) { return; }
server.print("<h1>");
server.print(lightLevel); server.print('%');
server.print(' ');
server.print(temperatureCentigrade); server.print('C');
server.print(' ');
server.print(temperatureFarenheit); server.print('F');
server.print("</h1>");
}
static const int referencePin = 3;
static const int lightPin = 4;
static const int temperaturePin = 5;
void sense(unsigned long now) {
int referenceRaw = analogRead(referencePin);
int lightRaw = analogRead(lightPin);
lightLevel = 100 - ((100UL * lightRaw) / 1023);
int temperatureRaw = analogRead(temperaturePin);
float temperatureVolts = (temperatureRaw * 5.0) / 1023.0;
temperatureCentigrade = (temperatureVolts - 0.5) * 100.0;
temperatureFarenheit = (temperatureCentigrade * 1.8) + 32.0;
Serial.print(referenceRaw);
Serial.print(' ');
Serial.print(lightRaw);
Serial.print(' ');
Serial.print(lightLevel);
Serial.print(' ');
Serial.print(temperatureRaw);
Serial.print(' ');
Serial.print(temperatureVolts);
Serial.print(' ');
Serial.print(temperatureCentigrade);
Serial.print(' ');
Serial.println(temperatureFarenheit);
then = now;
delay(1);
}
void sense() {
sense(millis());
}
static const byte __attribute__((__progmem__)) myMacAddress[] = { 0x90, 0xa2, 0xda, 0x0d, 0x03, 0x4c };
static const byte __attribute__((__progmem__)) myIpAddress[] = { 192, 168, 1, 223 };
static const byte __attribute__((__progmem__)) myGatewayAddress[] = { 192, 168, 1, 1 };
static const byte __attribute__((__progmem__)) mySubnetMask[] = { 255, 255, 255, 0 };
WebServer webServer;
#define countof(_ARRAY_) (sizeof(_ARRAY_)/sizeof(_ARRAY_[0]))
#define flash2sram(_TO_, _FROM_, _COUNT_) byte _TO_[_COUNT_]; memcpy_P(_TO_, _FROM_, sizeof(_TO_))
void setup() {
Serial.begin(9600);
flash2sram(tempMacAddress, myMacAddress, countof(myMacAddress));
flash2sram(tempIpAddress, myIpAddress, countof(myIpAddress));
flash2sram(tempGatewayAddress, myGatewayAddress, countof(myGatewayAddress));
flash2sram(tempSubnetMask, mySubnetMask, countof(mySubnetMask));
Ethernet.begin(tempMacAddress, tempIpAddress, tempGatewayAddress, tempSubnetMask);
webServer.setDefaultCommand(&getIndexHtml);
webServer.addCommand("index.html", &getIndexHtml);
webServer.begin();
sense();
}
void loop() {
unsigned long now = millis();
if ((now - then) > 1000) {
sense(now);
}
webServer.processConnection();
}
Friday, January 20, 2012
How to Contribute to the Robert Dixon Scholarship Fund
Wright State University Foundation3640 Colonel Glenn Hwy.Dayton, OH 45435
Thursday, January 19, 2012
The Robert Dixon Scholarship Fund
Wright State University Foundation3640 Colonel Glenn Hwy.Dayton, OH 45435
Tuesday, January 17, 2012
Can what you don't know hurt you?
#include <arduino.h>
int main(void)
{
init();
#if defined(USBCON)
USB.attach();
#endif
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}
void digitalWrite(uint8_t pin, uint8_t val)
{
uint8_t timer = digitalPinToTimer(pin);
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *out;
if (port == NOT_A_PIN) return;
// If the pin that support PWM output, we need to turn it off
// before doing a digital write.
if (timer != NOT_ON_TIMER) turnOffPWM(timer);
out = portOutputRegister(port);
uint8_t oldSREG = SREG;
cli();
if (val == LOW) {
*out &= ~bit;
} else {
*out |= bit;
}
SREG = oldSREG;
}
int analogRead(uint8_t pin)
{
uint8_t low, high;
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
if (pin >= 54) pin -= 54; // allow for channel or pin numbers
#elif defined(__AVR_ATmega32U4__)
if (pin >= 18) pin -= 18; // allow for channel or pin numbers
#else
if (pin >= 14) pin -= 14; // allow for channel or pin numbers
#endif
#if defined(__AVR_ATmega32U4__)
pin = analogPinToChannel(pin);
ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
#elif defined(ADCSRB) && defined(MUX5)
// the MUX5 bit of ADCSRB selects whether we're reading from channels
// 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
#endif
// set the analog reference (high two bits of ADMUX) and select the
// channel (low 4 bits). this also sets ADLAR (left-adjust result)
// to 0 (the default).
#if defined(ADMUX)
ADMUX = (analog_reference << 6) | (pin & 0x07);
#endif
// without a delay, we seem to read from the wrong channel
//delay(1);
#if defined(ADCSRA) && defined(ADCL)
// start the conversion
sbi(ADCSRA, ADSC);
// ADSC is cleared when the conversion finishes
while (bit_is_set(ADCSRA, ADSC));
// we have to read ADCL first; doing so locks both ADCL
// and ADCH until ADCH is read. reading ADCL second would
// cause the results of each conversion to be discarded,
// as ADCL and ADCH would be locked when it completed.
low = ADCL;
high = ADCH;
#else
// we dont have an ADC, return 0
low = 0;
high = 0;
#endif
// combine the two bytes
return (high << 8) | low;
}
Monday, January 16, 2012
Pulse-Width Modulation with Arduino
int sensorPin = 0;
int motorPin = 9;
int meterPin = 10;
int logicPin = 11;
int ledPin = 13;
volatile uint8_t * pointer = 0;
uint8_t mask = 0;
int tick = 0; /* 0..99 */
int dutyCycle = 0; /* 0..100 */
unsigned int period = 20; /* microseconds duration */
long sample = 0; /* 0.5 seconds */
long iteration = 0; /* 0..(sample - 1) */
boolean before = false; /* true or false */
unsigned long then = 0; /* microseconds elapsed */
void setup() {
pinMode(motorPin, OUTPUT);
digitalWrite(motorPin, LOW);
pinMode(meterPin, OUTPUT);
digitalWrite(meterPin, LOW);
pinMode(logicPin, OUTPUT);
digitalWrite(logicPin, LOW);
pointer = portOutputRegister(digitalPinToPort(motorPin));
mask = digitalPinToBitMask(motorPin) | digitalPinToBitMask(meterPin) | digitalPinToBitMask(logicPin) | digitalPinToBitMask(ledPin);
sample = 1000000L / period / 4;
then = micros();
}
void toggle() {
for (long ii = 0; ii < 25000000; ++ii) {
*pointer |= mask;
*pointer &= ~mask;
}
}
void square() {
boolean state = (tick >= (100 - dutyCycle));
if (state != before) {
uint8_t oldSREG = SREG;
cli();
if (state) {
*pointer |= mask;
} else {
*pointer &= ~mask;
}
SREG = oldSREG;
before = state;
}
tick = (tick + 1) % 100;
}
void timing() {
unsigned long now = micros();
unsigned int duration = now - then;
if (duration < period) {
delayMicroseconds(period - duration);
}
square();
then = now;
}
void control() {
timing();
if (iteration == 0) {
long value = analogRead(sensorPin) / (1024 / 16);
dutyCycle = (value * 100) / 15;
}
iteration = (iteration + 1) % sample;
}
void pwm() {
dutyCycle = analogRead(sensorPin) / 4; /* 0..255 */
analogWrite(motorPin, dutyCycle);
analogWrite(meterPin, dutyCycle);
analogWrite(logicPin, dutyCycle);
delay(250);
}
void loop() {
control();
}