Show Posts
Pages: [1] 2 3 ... 9
1  Using Arduino / Networking, Protocols, and Devices / Re: Odd issue with DS1307 (Refuses to work WITH battery) on: October 05, 2013, 03:01:15 am
Nevermind I figured it out, turned out my USB was only supplying 4.21V which was low enough to trigger the DS1307 into battery mode, hooked it up to an actual 5v supply and all is well.
2  Using Arduino / Networking, Protocols, and Devices / Odd issue with DS1307 (Refuses to work WITH battery) on: October 05, 2013, 02:53:58 am
Having an odd issue with DS1307, when battery is applied (CR2032 3V battery with 3.44V coming off of it) the RTC will not respond on I2C, though I can see the oscillator happily ticking away on scope, I can see the data and clock coming from the AVR, but it refuses to give any data out, however remove the battery (let that pin float), and it will respond properly to I2C, and never even loses time, any ideas?  I have checked and all polarities are correct, quite baffling!  Infact it even keeps time off of the battery, but I have to remove the battery first while powered up to get the time again.
3  Using Arduino / Programming Questions / Re: Need help troubleshooting variable not getting set by interrupt on: November 18, 2012, 07:04:35 am
I must say this project has been a hugely important learning experience for me, it really helped me grasp some deeper concepts I hadn't really wrapped myself around yet, I am also starting to realize just how much is possible if you think outside of the arduino core smiley.

This project is far from done, I still have code to put in to make it work as an I2C slave as well, this way it will support either PWM input OR I2C, main reason is because I am also building a custom 433MHz bidirectional radio system for this airplane and once that is complete it will have an I2C bus, this way I can give very precise commands and also read some data back from the controller, but until that is complete I want to still be able to fall back on standard RC receiver PWM.  I also want to remove all use of delays in the code and use timers, it really isn't all that required per-say on this project, but I want my code to be as efficient as possible.

I will be sure to come back and post a video of the airplane working with all of the high powered lights once I have it installed on the plane smiley.
4  Using Arduino / Programming Questions / Re: Need help troubleshooting variable not getting set by interrupt on: November 18, 2012, 06:32:30 am
Success!  After using my debugger code, which BTW had errors posted above, but I changed it to show working code.  Basically it boiled down to variable decelerations!  In one case an int was being put into a byte so that was screwing up that value, then in a few places I had unsigned int's being put into signed int's as well.  After finding those bugs and fixing all works as well as should be, and BTW the timing is quite accurate, using the scope I can easily measure the width of the PWM outputs, and compared to the measurements my interrupts are measuring it is pretty much spot on and the action is quite smooth as can be seen in the video below.

https://www.youtube.com/watch?v=LenmLVkkPis

Pictured below are screenshots from the scope showing the frameTime variable which is a calculation of the width of the pulse from the RX, normally 1000us is the lowest, and 2000us is the highest, the first is the throttle stick all the way down and reads 1116us which is within normal limits and indeed matches the width from the RX quite damn closely as measured with the scope.  The second picture is with throttle stick at 50% and reads 1525us, and the final picture is with the throttle at 100% and the reading being 1927.  all measurements are very consistent, I am quite happy now!
5  Using Arduino / Programming Questions / Re: Need help troubleshooting variable not getting set by interrupt on: November 18, 2012, 01:29:22 am
http://code.google.com/p/arduino-tiny/source/browse/trunk/libraries/PinChangeInterrupt/PinChangeInterrupt.cpp
6  Using Arduino / Programming Questions / Re: Need help troubleshooting variable not getting set by interrupt on: November 18, 2012, 01:11:51 am
Yeah if I cant figure it out with my current method I will end up using the software serial, I also found a special ISP for the tiny (based on arduino ISP) that uses the MISO pin to relay serial via the arduino to serial which I may try.
7  Using Arduino / Programming Questions / Re: Need help troubleshooting variable not getting set by interrupt on: November 18, 2012, 12:08:37 am
Hi
  Fair enough comment on the library. I guess that most people see attaching two different handlers to a single pin as being something that is not supported at the hardware level, if it works using the library, it maybe by a side effect rather than a design intention - its better not to build projects that rely on side effects.

I can appreciate that it must be very hard to do these things without serial, but testing a single channel version using the single ISR with change interrupts will simplify the task a little.

Duane B


EXT interrupts are limited and do hardware RISING/FALLING detection and can only detect either one or the other at a time, but PC interrupts are triggered whenever any pin on the entire port change.  All the library does when an interrupt is given is check if the pin state is high or low, and call the appropriate callback for RISING/FALLING.

It's certainly a timing issue at this point somewhere, because I did have it working perfectly with only a single in/out, but I wrote 90% of that code at work with no chip on me to test as I went along hehe.  I ended up writing a little routine set to output bytes and ints to a digital pin which I can see with my oscope, I tested the single byte version this morning and it worked quite well to see some of the variables, so when I get home I can now check the counters and timers and see exactly what sort of measurement result on the width timing it is coming up with, it has to be higher then it should because it binds but assumes it is getting a full power signal reguardless of the pulse width.

Just for reference here are the few routines I came up with to see variables on scope, it's simple and basic and works hehe:
Code:
void debugPulse(int time) {
// A simple debugging routine to pulse pin 0 to debug variables using a scope
  digitalWrite(0,HIGH);
  delayMicroseconds(time);
  digitalWrite(0,LOW);
}
void debugPrintByte(byte bOut) {
// A simple function to pulse out a byte in bits, 50us width = 1, 10us width = 0
  if (bOut & 1) {
    debugPulse(50);
  } else {
    debugPulse(10);
  }
  delayMicroseconds(5);
  if (bOut & 2) {
    debugPulse(50);
  } else {
    debugPulse(10);
  }
  delayMicroseconds(5);
  if (bOut & 4) {
    debugPulse(50);
  } else {
    debugPulse(10);
  }
  delayMicroseconds(5);
  if (bOut & 8) {
    debugPulse(50);
  } else {
    debugPulse(10);
  }
  delayMicroseconds(5);
  if (bOut & 16) {
    debugPulse(50);
  } else {
    debugPulse(10);
  }
  delayMicroseconds(5);
  if (bOut & 32) {
    debugPulse(50);
  } else {
    debugPulse(10);
  }
  delayMicroseconds(5);
  if (bOut & 64) {
    debugPulse(50);
  } else {
    debugPulse(10);
  }
  delayMicroseconds(5);
  if (bOut & 128) {
    debugPulse(50);
  } else {
    debugPulse(10);
  }

}
void debugPrintInt(int iOut) {
  // This function will outpit all 16 bits of an int on pin 0
  static byte singleByte = 0;
  singleByte |= (255 & (iOut & 1));
  singleByte |= (255 & (iOut & 2));
  singleByte |= (255 & (iOut & 4));
  singleByte |= (255 & (iOut & 8));
  singleByte |= (255 & (iOut & 16));
  singleByte |= (255 & (iOut & 32));
  singleByte |= (255 & (iOut & 64));
  singleByte |= (255 & (iOut & 128));
  debugPrintByte(singleByte);
  delayMicroseconds(20);
 singleByte = iOut >> 8;
  debugPrintByte(singleByte);
}

8  Using Arduino / Programming Questions / Re: Need help troubleshooting variable not getting set by interrupt on: November 17, 2012, 03:42:48 pm
Ok I wrote a little function to bitbang a byte to a pin so I could see on oscilloscope... now I need to make one that can do multibyte so I can see whats going on with timer variables because I couldn't find any issues with any variable that is just a byte.  The flags are working fine, though the output level goes to 255 every time it binds, so that tells me the timer isn't working properly for some reason.
9  Using Arduino / Programming Questions / Re: Need help troubleshooting variable not getting set by interrupt on: November 17, 2012, 03:04:27 pm
This is not the PinchangeInt library, it is the PinchangeInterrupt library for the ATTINY core,  I dunno why everyone want's to focus on the interrupts when they work and the last bit of code does not even apply to this library... At either rate I AM open to ideas and if everyone thinks it's better to keep track of the actual rise/fall change myself vs letting the library do it I can, but the way it's coded and how simple it is I do not see it making much of a difference...

This type of project is REALLY tough without a serial port!!!  I just have no IDEA how to tell what is going on... I think I will use a pin for debugging and just bitbang to my oscilloscope to try to debug...


10  Using Arduino / Programming Questions / Re: Need help troubleshooting variable not getting set by interrupt on: November 17, 2012, 07:16:52 am
1. Try working with just one think (say headlight) at a time. Get that running then extend it to cover the other things.

2. I don't think you can do this
Code:
attachPcInterrupt(headlightInput,headlightOn,RISING);
 attachPcInterrupt(headlightInput,headlightOff,FALLING);
 

Does the documentation explicitly say that you can have more that one interrupt attached to a pin AT THE SAME time?

Mark
The library does it in software, in all actuality pin change is called when there is a pin change on ANY of the pins on that port, and the library takes the ISR and does internal tracking of rising/falling and calls the appropriate callback.  The callbacks themselves are working fine, one thing I found was changing UINT references to UNSIGNED INT and such made a difference and the main loop started to see something in the variable, then my RC TX battery died so now it's charging and I can't diagnose farther until then smiley.
11  Using Arduino / Programming Questions / Need help troubleshooting variable not getting set by interrupt on: November 17, 2012, 05:15:59 am
This is running on an ATTINY84.  I am stumped in that the statusMask variable is not ever being set by the main loop, though I know for a fact the interrupts are being called because a diagnostic LED tell's me so, I have ran the diagnostic LED in every conceivable spot, and the one place I never get a response is inside of if (statusMask), which makes no sense because the interrupt does indeed get triggered, any ideas?


Code:
#include <PinChangeInterrupt.h>


/*
 MatCat Airplane Lighting Contoller
 
 PWM and I2C connectivity to drive 3 channels of lighting.
 
 This code is open source and free to be used by whomever
 for non-commercial purposes.  Please keep the proper
 copyright when distributing this code, thank you!
 */


// PWM Outputs
unsigned int headlights = 2;
unsigned int navlights = 3;
unsigned int floodlights = 4;

// PWM Inputs
unsigned int headlightInput = 5;
unsigned int navlightInput = 6;
unsigned int floodlightInput = 7;

// Operational Parameters
int strobeFrequency = 1000;        // 1 second between pulses
int strobeLength = 30;             // 30ms strobe length
int strobeBreak = 50;              // 50ms break between fast pulses

volatile byte headlightLevel = 0;           // Output buffer level for headlights
volatile byte navlightLevel = 0;            // Output buffer level for navlights
volatile byte floodlightLevel = 0;          // Output buffer level for floodlights
volatile uint16_t oldHeadLevel = 0;          // Old lighting level
volatile uint16_t oldNavLevel = 0;
volatile uint16_t oldFloodLevel = 0;
volatile uint8_t oldHeadOut = 0;
volatile uint8_t oldNavOut = 0;
volatile uint8_t oldFloodOut = 0;
// Bit mask for keeping track of whats going on

static uint8_t HEADLIGHT_FLAG = 1;
static uint8_t NAVLIGHT_FLAG = 2;
static uint8_t FLOODLIGHT_FLAG = 4;
static uint8_t I2C_FLAG = 8;                 // Indicates the usage of I2C over PWM

uint8_t hasBound = 0;               // A variable to keep track of being bound

volatile uint8_t statusMask;        // This is the actual mask variable

// Timers to keep track of pulse widths
volatile unsigned long headlightTimer = 0;
volatile unsigned long navlightTimer = 0;
volatile unsigned long floodlightTimer = 0;

// Timers for other operations
unsigned long lastStrobeTime;       // Used for strobe timing
unsigned long lastFrameTime;        // When was the last PWM frame?
unsigned int secondTime;           // A special timer for measuring a second 
uint8_t rxFrequency = 0;                // Rated in HZ, normal is 50
uint16_t frameCount = 0;            // Count of frames per second

void setup()  {
  // Setup inputs
  pinMode(headlightInput, INPUT);
  pinMode(navlightInput, INPUT);
  pinMode(floodlightInput, INPUT);

  // Setup outputs
  pinMode(headlights,OUTPUT);
  pinMode(navlights,OUTPUT);
  pinMode(floodlights,OUTPUT);

  // Setup a few variables
  lastStrobeTime = millis();
  secondTime = millis();
  // Let's do a little init. routine
  strobeLight(headlights,160,100);
  delay(100);
  strobeLight(navlights,160,100);
  delay(100);
  strobeLight(floodlights,160,100);
  delay(500);
  for (int a = 0; a < 5; a++) {
    strobeAll(160,160,160,30);
    delay(100);
  }
  // Ok now let's setup some interupts
  attachPcInterrupt(headlightInput,headlightOn,RISING);
  attachPcInterrupt(headlightInput,headlightOff,FALLING);
  attachPcInterrupt(navlightInput,navlightOn,RISING);
  attachPcInterrupt(navlightInput,navlightOff,FALLING);
  attachPcInterrupt(floodlightInput,floodlightOn,RISING);
  attachPcInterrupt(floodlightInput,floodlightOff,FALLING);

}

void loop()  {
  // Setup some local variables for reading
  // the values set by interrupts. 
  static uint16_t headLevel = 0;   
  static uint16_t navLevel = 0;
  static uint16_t floodLevel = 0;
  static uint8_t flagmask = 0;
  static uint8_t updateFlag = 0;   
  static long frameTime = 0;
  static uint8_t secondFlag = 0;
  static uint8_t strobeFlag = 0;
 
  if (statusMask) {
    // We need to update what's going on.
    noInterrupts();
    flagmask = statusMask;
    if (flagmask & HEADLIGHT_FLAG) {
     
      // Headlights have been updated
      if (headlightLevel != oldHeadLevel) {
        headLevel = headlightLevel;
        oldHeadLevel = headLevel;
        updateFlag |= HEADLIGHT_FLAG;
      }
      // Let's capture the frame time for calculation later
      frameTime = (uint16_t)(micros() - lastFrameTime);
      lastFrameTime = micros();
    }
    if (flagmask & NAVLIGHT_FLAG) {
      // Navs have been updated
      if (navlightLevel != oldNavLevel) {
        navLevel = navlightLevel;
        oldNavLevel = navLevel;
        updateFlag |= NAVLIGHT_FLAG;
      }
    }
    if (flagmask & FLOODLIGHT_FLAG) {
      // Floods have been updated
      if (floodlightLevel != oldFloodLevel) {
        floodLevel = floodlightLevel;
        oldFloodLevel = floodLevel;
        updateFlag |= FLOODLIGHT_FLAG;
      }
    }
 
    // We need to clear the status flags from interrupts
    statusMask = 0;
   
    interrupts();
  }
  // Let's handle the second timer.
  if ((millis() - secondTime) >= 1000) {
    // A second has passed, reset the timer
    secondTime = millis();
    secondFlag = 1;
  }
 
  // Let's handle the strobe timer.
  if ((millis() - lastStrobeTime) >= strobeFrequency) {
    // We need to do a strobe...
    lastStrobeTime = millis();
    strobeFlag = 1;
  }
  if (frameTime > 0) {
    // It's a new frame from the RX, let's do some math
    frameCount++;  // Add to frame count
    if (secondFlag) {
      // The frameCount variable will tell us, should be close to 50
      rxFrequency = frameCount;
      frameCount = 0;  // Reset it
    }
  }
 
  if (rxFrequency > 30) {
    // We probably have a valid PWM signal, so consider it bound
    hasBound = 1;
  } else {
    // Either we are not bound or lost bound...
    hasBound = 0;
  }
 
  if (!hasBound) {
    // We need to continue looking for an input...
    strobeLight(headlights,50,15);      // Indicate looking for PWM
    delay(50);   
    strobeLight(navlights,50,15);      // Indicate looking for PWM
    delay(50);   
    strobeLight(navlights,50,15);      // Indicate looking for PWM
    delay(50);   
    strobeLight(navlights,50,15);      // Indicate looking for PWM
    delay(50);   
    strobeLight(navlights,50,15);      // Indicate looking for PWM
    delay(500);
  } else {
    // We are bound, so let's do what needs to be done
    // First we need to see if any of the levels need to be adjusted...
    uint8_t headOut = oldHeadOut;
    uint8_t navOut = oldNavOut;
    uint8_t floodOut = oldFloodOut;

    // Before we output the the power, we need to check if we have to strobe...
    if (strobeFlag) {
      // We need to do some strobing before actually setting the output
      strobeAll(255,255,255,strobeLength);
    }
    if (updateFlag & HEADLIGHT_FLAG) {
      // We need to change output of headlights
      headOut = map(headLevel,1000,2000,0,255);
      if (headOut < 40) {headOut = 0;}
      if (headOut > 210) {headOut = 255;}
      oldHeadOut = headOut;
      analogWrite(headlights,headOut);
    }
    if (updateFlag & NAVLIGHT_FLAG) {
      // We need to change output of headlights
      navOut = map(navLevel,1000,2000,0,255);
      if (navOut < 40) {navOut = 0;}
      if (navOut > 210) {navOut = 255;}
      oldNavOut = navOut;
      analogWrite(navlights,navOut);
    }
    if (updateFlag & FLOODLIGHT_FLAG) {
      // We need to change output of headlights
      floodOut = map(floodLevel,1000,2000,0,255);
      if (floodOut < 40) {floodOut = 0;}
      if (floodOut > 210) {floodOut = 255;}
      oldFloodOut = floodOut;
      analogWrite(floodlights,floodOut);
    }
  }
}
void strobeXTimes(int x) {
  for (int a = 0;a < x;a++) {
    strobeLight(headlights,255,20);
    delay(50);
  }
}
void strobeAll(byte valuehead,byte valuenav, byte valueflood, int duration) {
  analogWrite(headlights,valuehead);
  analogWrite(navlights,valuenav);
  analogWrite(floodlights,valueflood);
  delay(duration);
  analogWrite(headlights,oldHeadOut);
  analogWrite(navlights,oldNavOut);
  analogWrite(floodlights,oldFloodOut);
}

void strobeLight(int light,byte value,int duration) {
  analogWrite(light,value);
  delay(duration);
  if (light == headlights) {
      analogWrite(light,oldHeadOut);
  }
  if (light == navlights) {
      analogWrite(light,oldNavOut);
  }
  if (light == floodlights) {
      analogWrite(light,oldFloodOut);
 }
}

void headlightOn() {
  // Do something when we have headlight PWM coming in...
  headlightTimer = micros();   
}
void headlightOff() {
  // Do something when we have headlight PWM Pulse finished...
  headlightLevel = (uint16_t)(micros() - headlightTimer);
  statusMask |= HEADLIGHT_FLAG;
}
void navlightOn() {
  navlightTimer = micros();
}
void navlightOff() {
  navlightLevel = (uint16_t)(micros() - navlightTimer);
  statusMask |= NAVLIGHT_FLAG;
}
void floodlightOn() {
  floodlightTimer = micros();
}
void floodlightOff() {
  floodlightLevel = (uint16_t)(micros() - floodlightTimer);
  statusMask |= FLOODLIGHT_FLAG;
}
12  Topics / Robotics / Reading 3 PWM signals on ATTINY84? (from RC RX) on: November 15, 2012, 11:04:15 pm
I am wanting to read 3 channels from an RC TX, note that output is PWM NOT PPM.  I have seen examples of using pin change interrupts on arduino to look for when it goes high, have timer count until it goes low and get pulse width, but how do I do this on ATTINY84?  I have pin's 8 through 10 connected to the PWM inputs from the RX and I need to read all 3 of them.  The module itself will take the values and appropriately generate a PWM signal on pins 5 to 7 to control 3 sets of high power LEDs.

Basically I am not sure how to 1, enable the interrupt properly, 2, accurately measure the time (use timer, or in main loop?), 3, will setting a timer on timer1 effect PWM generation, and if so how can I tackle that?

Thanks ahead for the guidance!
13  Using Arduino / Programming Questions / How to take 2 sets of coordinates and altitude and calculate angle for Servos on: November 13, 2012, 11:15:35 pm
Basically I am wanting a way to calculate the correct PWM to aim a camera on a pan and tilt servo system at a coordinate by calculating based on it's own coordinates.  This does need to take into account altitude as well.  This will be used on my FPV airplane, and I want to have the ability to have the camera stay locked onto a spot on the ground, but I am not quite sure where to start to even make the calculations!  (Assuming both sets of coordinates are known of course).

I appreciate any help anyone can offer!
14  Using Arduino / LEDs and Multiplexing / Re: Looking for advice on driving 3w and 1w LED's on: November 10, 2012, 02:56:16 am
A question... I am using these cat4101 constant current sink drivers, and I am wondering... SINCE it is constant current, does that mean if I parallel multiple LED's to the driver that each LED will just get LED Count / Current Sink ma of current?  Technically having the LED paralleled means that each LED will see 5v, and the sink will only sink 700ma total as that is how it is set, so if I parallel 2 white LED's that at full power consume 700ma each with a forward voltage of 3.5v onto a 700ma sink, then it should in reality split equally the current allowing only 350ma through each, and dissipating 1.25v x2 to heat (.5v is used by current driver), and continue the pattern regardless of the number of LED's... am I correct in my understanding, and or is there more to understand exactly how I would figure it out properly, thanks!
15  Using Arduino / LEDs and Multiplexing / Re: Looking for advice on driving 3w and 1w LED's on: November 09, 2012, 10:05:49 pm
I will use my SDR and experiment and see if I pick up any odd frequencies from using the lights as is... Mainly RC airplanes have lights so I am not thinking it's going to be a big issues, especially as long as they aren't messing with 433MHz or 1.3GHz hehe.
Pages: [1] 2 3 ... 9