Show Posts
Pages: [1] 2
1  Using Arduino / Programming Questions / Re: IR decode to contact closure - Kind of works, but trying to improve code on: October 29, 2013, 06:34:03 am
I'm not sure if it's me, but things are a little hazy ...

Sorry about that.  I greatly improved the wording of my first post to explain the circuit layout and what I'm needing to do.

Thanks!
2  Using Arduino / Programming Questions / IR decode to contact closure - Kind of works, but trying to improve code on: October 29, 2013, 12:07:58 am
I'm trying to improve the code of my simple IR decoder and button pusher sketch I've compiled for an attiny85.  The purpose of the sketch is to allow me to control 3 physical pushbuttons of an external circuit with a standard IR remote control.  

My attiny85 shares a common ground with the external circuit, and the 3 normally open pushbuttons of the external circuit are wired back to my pins 0, 1 and 2.  The buttons on the external board are normally ~5v, and pushing a button grounds them to 0, so my sketch needs to function the same way.  

I don't see any pullup resistors on the buttons of the external board, the buttons wire back directly to pins on an unmarked IC.  For this reason I was trying to steer these pins high with the internal 20K pullups using my circuit to avoid any ambiguity, and then drop them to ground to register a button press.

Code:
//----------------------------------------------------------------------------------------------------------------------
// IR_to_Button_Press
// This program for an attiny85 uses IR codes to simulate button presses on a three normally-open pushbuttons
// Shorting pushbutton to ground registers a "press"
// IR code decoding based on the TinyPCRemote by Nathan Chantrell http://nathan.chantrell.net
//
// Licenced under the Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) licence:
// http://creativecommons.org/licenses/by-sa/3.0/
//----------------------------------------------------------------------------------------------------------------------


// IR sensor connected to PB4 = ATtiny85 physical pin 3
// Using #define for timing purposes per original code
#define IRpin_PIN   PINB
#define IRpin   4

#define MAXPULSE 5000     // max IR pulse length, default 5 milliseconds
#define NUMPULSES 100     // max IR pulse pairs to sample
#define RESOLUTION 2      // time between IR measurements

uint16_t pulses[NUMPULSES][2];  // pair is high and low pulse
uint8_t currentpulse = 0;       // index for pulses we're storing

const int UpButton = 2;       //  Screen UP button connected to PB2 = ATtiny85 physical pin 7
const int StopButton = 1;     //  Screen STOP button connected to PB1 = ATtiny85 physical pin 6
const int DownButton = 0;     //  Screen DOWN button connected to PB0 = ATtiny85 physical pin 5

void setup()
{
  pinMode(4, INPUT);   // Make sure IR pin is set as input
  pinMode(UpButton, INPUT);  // Putting UpButton in high impedance state to be pulled up
  pinMode(StopButton, INPUT);  // Putting StopButton in high impedance state to be pulled up
  pinMode(DownButton, INPUT);  // Putting DownButton in high impedance state to be pulled up
}

void loop()
{
  digitalWrite(UpButton, HIGH);        // Turn on internal pullup
  digitalWrite(StopButton, HIGH);      // Turn on internal pullup
  digitalWrite(DownButton, HIGH);      // Turn on internal pullup
  
  unsigned long irCode = listenForIR(); // Wait for an IR Code

  // Process the pulses to get our code
  for (int i = 0; i < 32; i++)
  {
    irCode = irCode << 1;
    if((pulses[i][0] * RESOLUTION) > 0 && (pulses[i][0] * RESOLUTION) < 500)
    {
      irCode |= 0;
    }
    else
    {
      irCode |= 1;
    }
  }

  // ---------------------------------------------------------------------------------------
  // Enter IR codes to watch for and desired outcomes this section
  // ---------------------------------------------------------------------------------------

  if (irCode == 2681863583)      // Screen Up command entered, simulate pressing 'Screen Up' pushbutton
  {
    pinMode(UpButton, OUTPUT);      // Setting UpButton as an OUTPUT gets out of high impedance mode
    digitalWrite(UpButton, LOW);      // Pull down to ground momentarily to trigger pushbutton
    delay(500);
    pinMode(UpButton, INPUT);      // Putting UpButton back in a high impedance state
  }

  else if (irCode == 2682912415)      // Screen Stop command entered, simulate pressing 'Screen Stop' pushbutton
  {
    pinMode(StopButton, OUTPUT);      // Setting StopButton as an output
    digitalWrite(StopButton, LOW);      // Pull stop button to ground momentarily
    delay(500);
    pinMode(StopButton, INPUT);      // Putting StopButton back in a high impedance state
  }

  else if (irCode == 2683961247)      // Screen Down command entered, simulate pressing 'Screen Down' pushbutton
  {
    pinMode(DownButton, OUTPUT);      // Setting DownButton as an output
    digitalWrite(DownButton, LOW);      // Pull down button to ground momentarily
    delay(500);
    pinMode(DownButton, INPUT);      // Putting DownButton back in a high impedance state
  }


} // loop end


// IR receive code
int listenForIR()
{
  currentpulse = 0;
  while (1)
  {
    unsigned int highpulse, lowpulse;  // temporary storage timing
    highpulse = lowpulse = 0; // start out with no pulse length

    while (IRpin_PIN & _BV(IRpin))   // got a high pulse
    {
      highpulse++;
      delayMicroseconds(RESOLUTION);
      if (((highpulse >= MAXPULSE) && (currentpulse != 0)) || currentpulse == NUMPULSES)
      {
        return currentpulse;
      }
    }
    pulses[currentpulse][0] = highpulse;

    while (! (IRpin_PIN & _BV(IRpin)))   // got a low pulse
    {
      lowpulse++;
      delayMicroseconds(RESOLUTION);
      if (((lowpulse >= MAXPULSE) && (currentpulse != 0)) || currentpulse == NUMPULSES)
      {
        return currentpulse;
      }
    }
    pulses[currentpulse][1] = lowpulse;
    currentpulse++;
  }
}


The IR decoding I 'borrowed' from Nathan Chantrell's TinyPCRemote, and I don't entirely know how it works or why some variables are defined in the way they are.  I think Nathan did a great job, and I just can't wrap my head around how it works.

The other area of concern to me is how I handled the pin modes of the 3 pushbuttons I'm manipulating.  At first I made the sketch work by digital writing the 3 pushbuttons as HIGH outputs, and dropping to LOW momentarily to trigger the button presses, but I realized I can utilize the internal pull-ups by writing HIGH input and forego the external resistors.  Now I've since heard about INPUT_PULLUP, and I'm not sure if its more appropriate for my use or not.

Also, any other tips or advice would be very greatly appreciated.  I'm going to box this thing up inside a motorized projector screen enclosure and it will be fairly difficult to get back into it down the road.

Thanks for looking
3  Using Arduino / Project Guidance / Re: Creating specific PWM routine with POT adjustments and no delay() on: March 29, 2011, 11:00:29 pm
Thanks johnwasser, this works great.


I did notice however I no longer have direct control over the pulse width as its own entity, but rather as a fraction of the period, in a 10-bit range. (0-1023)

I would agree this is probably the best way to do normal PWM tasks but in my case I need to maintain a specific pulse width regardless of a changing frequency.

I'm having a tough time wrapping my head around the math equation required to create a 100-300 uS pulse for any given period (or frequency) and expressed as a number 0-1023.


I'm sure I'll think of it within a few days but my brain is NOT wired for programming...
4  Using Arduino / Project Guidance / Re: Arduino Air Pump on: March 29, 2011, 09:16:45 pm
That could be a better solution for the relatively low pressures involved.  Might have to double check that it's got the oomph to get the balloon started however.
5  Using Arduino / Project Guidance / Re: decibel meter with LCD screen on: March 29, 2011, 06:38:41 pm
I made an SPL meter with my Arduino when I first got it, with an LCD and frequency feedback as well.

Hopefully I posted the code in the thread I had made on this forum..maybe there's something you can use.

(note it was designed to measure low frequency, high output stuff so I never tested it on anything above 100Hz or so...)
6  Using Arduino / Project Guidance / Re: Arduino Air Pump on: March 29, 2011, 06:30:52 pm
I would imagine gutting a cheap 12v portable tire inflater (for roadside repairs) and connecting it via mostfet or relay would solve your problem quite simply.
7  Using Arduino / Project Guidance / Re: How to remotely mount an Arduino? on: March 29, 2011, 06:29:12 pm
Have you seen this article yet?

http://www.esawdust.com/blog/serial/files/Hardened-USB-Extension-Cable.html
8  Using Arduino / Project Guidance / Re: Creating specific PWM routine with POT adjustments and no delay() on: March 28, 2011, 05:39:39 pm
That Timer1 library sounds like it could be very useful, if you can find the link I'd be very grateful.

And I'm running an arduino duemilanove with the 328 uC.
9  Using Arduino / Project Guidance / Re: Creating specific PWM routine with POT adjustments and no delay() on: March 28, 2011, 01:23:40 am
The exact number of increments in either field doesn't concern me too greatly, the more the better of course but steps of 10-20Hz for the frequency and maybe 25 uS steps on the pulsewidth would be fine.

I'm occasionally getting some wrong pulses as it is with my code, part of the reason I'm looking for an alternative.  Incorrect pulse width would be my primary concern.  If the wrong pulses are missed pulses that's OK.  However I never want a pulse greater than 300 uS.  Incorrect frequency shouldn't be as big of a concern.

Additionally the arduino will be outputting the frequency and pulsewidth information to an LCD readout.

Thank you!
10  Using Arduino / Project Guidance / Creating specific PWM routine with POT adjustments and no delay() on: March 28, 2011, 12:03:47 am
I'm needing to create a PWM routine with a variable frequency and variable pulsewidth, controlled through two POTs.

The frequency should be adjustable, from 1-200 Hz
The pulsewidth should be adjustable, from 100-300 uS

It seemed pretty simple but I'm no programmer and basically pieced this together from code snippets I've found so I'm thinking there is a simpler, better way of doing this?  Also since I'm counting microseconds in a 'long' I'm not sure what will happen when this variable overflows?

I tried it with a simple delayMicroseconds() at first and ran into timing issues trying to read the pots AND keep the pulse going steady.

Anyway here's my code:

Code:
// constants won't change. Used here to set pin numbers:
const int frequencyPin = A0;    // pin that the frequency sensor is attached to
const int pulsewidthPin = A5;    // pin that the pulse-width sensor is attached to
const int outputPin = 9;        // pin that the LED is attached to

// Variables will change:
long previousMicros = 0;        // will store last time LED was updated
long period = 0;           // period at which to blink (microseconds)

int frequencyValue = 0;         // the frequency value
int frequencyMin = 1023;        // minimum frequency value
int frequencyMax = 0;           // maximum frequency value

int pulsewidthValue = 0;         // the pulsewidth value
int pulsewidthMin = 1023;        // minimum pulsewidth value
int pulsewidthMax = 0;           // maximum pulsewidth value


void setup() {
  // set the digital pin as output:
  pinMode(outputPin, OUTPUT);

  // turn on LED to signal the start of the calibration period:
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);

  // calibrate during the first five seconds
  while (millis() < 5000) {
    frequencyValue = analogRead(frequencyPin);
    pulsewidthValue = analogRead(pulsewidthPin);

    // record the maximum frequency value
    if (frequencyValue > frequencyMax) {
      frequencyMax = frequencyValue;
    }

    // record the minimum frequency value
    if (frequencyValue < frequencyMin) {
      frequencyMin = frequencyValue;
    }
   
    // record the maximum pulsewidth value
    if (pulsewidthValue > pulsewidthMax) {
      pulsewidthMax = pulsewidthValue;
    }

    // record the minimum pulsewidth value
    if (pulsewidthValue < pulsewidthMin) {
      pulsewidthMin = pulsewidthValue;
    } 
}
}

void loop() {
  // read the sensor:
  frequencyValue = analogRead(frequencyPin);
  pulsewidthValue = analogRead(pulsewidthPin);

  // apply the calibration to the frequency reading
  frequencyValue = map(frequencyValue, frequencyMin, frequencyMax, 1, 200);

  // in case the frequency value is outside the range seen during calibration
  frequencyValue = constrain(frequencyValue, 1, 200);

  // apply the calibration to the pulsewidth reading
  pulsewidthValue = map(pulsewidthValue, pulsewidthMin, pulsewidthMax, 100, 300);

  // in case the pulsewidth value is outside the range seen during calibration
  pulsewidthValue = constrain(pulsewidthValue, 100, 300);


  // check to see if it's time to blink the LED; that is, if the
  // difference between the current time and last time you blinked
  // the LED is bigger than the interval at which you want to
  // blink the LED.
 
  unsigned long currentMicros = micros();  // this will hold the current time
  period = 1000000/frequencyValue;  // calculate the time between on-pulses
 
  if(currentMicros - previousMicros > period) {
    // save the last time you blinked the LED
    previousMicros = currentMicros;   

    digitalWrite(outputPin, HIGH);
    delayMicroseconds(pulsewidthValue);
    digitalWrite(outputPin, LOW);
  }
}
11  Forum 2005-2010 (read only) / Development / Re: Frequency Counter on: March 04, 2010, 12:56:11 am
Solved.  I was accidentally sending ± signal to arduino.  Vertical shift up fixed the issue.
12  Forum 2005-2010 (read only) / Development / Re: Frequency Counter on: February 28, 2010, 11:10:51 pm
It seems the frequency counter does work on my Arduino, as verified by the faulty grounding on my macbook sending a small 60Hz signal through my wooden desk and picked up by the bare Arduino PCB!

Unplugging the laptop fixes that anomaly but still the counter won't read any intentional signals!

Is there a minimum threshold voltage the signal must be for proper detection?  Will it read a sine wave?  Is there a "trigger" level that's not being met?  I would love to get this to work!
13  Forum 2005-2010 (read only) / Development / Re: Frequency Counter on: February 28, 2010, 11:23:39 am
I have tried using this library (with modification for 328) and example sketch but I'm not getting results to the console.  I'm using a Duemilanove with ATMega328.


It compiles and this is the output I see:
Code:
Frequency Counter
0  Freq: 0
1  Freq: 65536
2  Freq: 0
3  Freq: 0
4  Freq: 0
5  Freq: 0
6  Freq: 0

I've got a 250Hz square wave I'm trying to measure.  Should I be feeding this into digital pin 5 or analog pin 5?  I've tried every pin on the board with no luck.

Here's the sketch:


Quote



// Frequency Counter Lib example
//
#include <FreqCounter.h>

// Switch on LED on pin 13 each second


void setup() {
  pinMode(13, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(7, OUTPUT);
  Serial.begin(57600);        // connect to the serial port

 

  Serial.println("Frequency Counter");

}

unsigned long frq;
int cnt;

void loop() {
  
  // wait if any serial is going on
  FreqCounter::f_comp=106;
  FreqCounter::start(1000);
  
  while (FreqCounter::f_ready == 0)
  
  
  
  frq=FreqCounter::f_freq;
  Serial.print(cnt++);
  Serial.print("  Freq: ");
  Serial.println(frq);
  delay(200);


 
  
}  

14  Forum 2005-2010 (read only) / Interfacing / Re: calculate RMS voltage of audio signal? on: March 03, 2010, 01:38:10 am
Found this article which uses the same biasing technique to bring the AC signal out of negative territory.  I think this might work with a bit of amplification on the signal.

http://interface.khm.de/index.php/lab/experiments/arduino-realtime-audio-processing/
15  Forum 2005-2010 (read only) / Interfacing / Re: calculate RMS voltage of audio signal? on: March 02, 2010, 01:12:55 am
You mention conditioning the signal to an analog ground of ~2.5v.  Would this be accomplished by feeding a regulated 2.5v to the external "aref" pin?

I can understand the benefit of raising the center point to put the entire AC waveform in the ADC's useable range, any advice on how to go about  doing this would be great!
Pages: [1] 2