Vision System Program Architecture - Fio V3

Hello All,

I am trying to develop a vision system for my first Arduino project and I am looking for advice on the program architecture as well as the over all feasibility of such a project.

I have 6 I.R. LEDs and one I.R. receiver connected to a Fio V3. The plan is that each LED will flash at 30KHz, one at a time, in sequence. Depending on which LED is flashing at the time, the I.R. receiver detects the signal the Fio will be able to detect an obstacle in that particular direction. I chose to use 6 LEDs and one receiver in order to keep the weight down as the emitter/detector pairs would be too large and heavy.

I have searched online and from what I understand I will need to employ the advanced pulse width modulation functions, as I believe that I will need to call an interrupt however I have been unable to find any details on this. The best I have found is…

“The timers can also generate interrupts on overflow and/or match against either output compare register, but that’s beyond the scope of this article.”

I believe that I will need interrupts because the Fio will need to run this detection sequence in the background and the generate and interrupt when and object is detected.

In particular I am struggling with this bit of code.

void setup()
{
  pinMode(IR_PIN, OUTPUT);  // IR_PIN = Pin 3
  digitalWrite(IR_PIN, LOW);

  Serial.begin(9600);                // initialize serial communication:

 
  //setup interrupt interval: 180ms 
  Timer1.initialize(DURATION);
  Timer1.attachInterrupt(timerISR);
   
  //setup PWM: f=30Khz PWM=0.5 
  byte v = 4000 / 30;
  TCCR2A = _BV(WGM20);
  TCCR2B = _BV(WGM22) | _BV(CS20);
  OCR2A = v;
  OCR2B = v / 2
  
}

Can anyone suggest a good source for more information on advanced pulse width modulation?

Thanks in advance and any advice is appreciated.

Zeus

There seem to be two parts to the problem: generating the 30KHz signal on one pin at a time, and detecting and handling the returned signal. I guess the receiver will automatically detect the 30KHz signal when it is present, and you just need to monitor its output state. If you need to detect the 30KHz modulation yourself that will be more complex and you should probably be looking for an IR receiver library.

You seem to be planning to use interrupts for both parts. Unless you are already very familiar with using interrupts, I suggest you don't. It is a common misconception that you need interrupts in order to control multiple independent activities, but you don't. There are situations where interrupts are necessary to achieve particularly low latency in responding to an input event, but it's not obvious that's the case here. Using interrupts introduces significant design issues and is best avoided unless/until necessary.

To generate the 30KHz output you could do it entirely in software, or using a timer interrupt handler, or entirely in hardware. The first approach would be by far the easiest and simplest - just take the guts of the 'blink without delay' example sketch. The disadvantage of this approach is that you can't afford for your sketch to do anything else that will keep the CPU busy for longer than half your pulse duration - I don't know what else you intend it to do so I don't know how much of a problem that will be. Using a timer interrupt handler to schedule the 30KHz signal but doing the actual output in software would increase the complexity but reduce the CPU requirements. This would be a good compromise if you need to keep the CPU available for other things - the Timer library would be a good way to implement this approach. Doing it entirely in hardware would reduce the CPU load further but mean you need to work with the hardware timers at a lower level, which means you have a steeper learning curve. I suggest you take the easiest / simplest approach first, and move to the more complicated approaches if you find it is necessary.

The most appropriate way to handle the receiving side depends to some extent on how frequently you expect to switch emitters i.e. how much latency you can afford here. Assuming that you're going to let each emitter run for at least milliseconds and perhaps tens of milliseconds or longer, simply polling it's output at regular intervals shorter than the switching interval should be sufficient, and again you can do that either entirely in software (simplest) or using a hardware interrupt and then providing a mechanism for the interrupt handler to notify the code running in the main context about the detection - which will usually involve the main context polling some shared data. Having the main context simply poll the detector directly avoids a lot of complexity and issues associated with the use of interrupts, but using an interrupt handler to set a flag per detector and then polling and resetting the flags in the main context wouldn't be a lot more complicated. It's a trade-off between how keen you are to avoid complexity, versus how keen you are to avoid loading the CPU.

ps- if you print it out it's 37 pages long

Thank you both for you replies.

Peter,

You have given me a lot of good information to research and I had wondered if I was over complicating my solution, but I thought that there was no other option but to use interrupts. Fundamentally I struggle with how to emit a 30KHz pulse while at the same time scanning for it? I can see how to bit bang a 30KHs signal, but then I am stuck. I will look at the IR receiver library and see if something clicks.

On that note I read the following line with particular interest…

“It is a common misconception that you need interrupts in order to control multiple independent activities, but you don’t.”

Can you expand on this statement? I don’t think I can afford to completely tie up the CPU as I need to cycle through the 6 LEDs and monitor the receiver and then if detected stop briefly and send out the appropriate signal. Sending the signal should not take too long so I do not believe there will be any issues on the return. Detection on the other hand; I am not sure of how to integrate this into the program.

I had planned to let each emitter broadcast for a tenth of a second max. and the move on to the next LED. It could be longer or shorter, there is nothing really driving this.

“simply polling it’s output at regular intervals shorter than the switching interval should be sufficient, and again you can do that either entirely in software (simplest) or using a hardware interrupt and then providing a mechanism for the interrupt handler to notify the code running in the main context about the detection”

Can you elaborate on the above statement? Specifically what you mean by “switching interval” Are you saying that I have to poll the output at less than 1/30KHz? This is my first Arduino project and I am new to coding so sorry in advance for asking you to explain further.

Raschemmel,

I had come across both of those links in my research but did not see how they applied. I will have another go at it and see if anything comes to me the second time around.

Thanks again,

Zeus

ZeusDashing:
Fundamentally I struggle with how to emit a 30KHz pulse while at the same time scanning for it?

Have you got an IR receiver which will detect the 30KHz signal for you and tell you whether it's present? This isn't something you really want to do for yourself.

The code you posted in your initial post doesn't compile and you didn't mention that in your initial post. When you stated you were struggling with this bit of code, was that your cryptic way of saying this program doesn't compile ? (not trying to be sarcastic, just asking if you were implying it didn't compile without explicitly saying so) . I find it stanger still that no one else has pointed that out.

If you want to "automatically" flash an LED ( in the background ) you can do it with this code:-

/* Code to pulse pin 3 with a modulated signal
* Can be used to drive an IR LED to keep a TSOP IR reciever happy
* This allows you to use a modulated reciever and a continious beam detector
* By Mike Cook Nov 2011 - Released under the Open Source licence
*/
 volatile byte pulse = 0;

ISR(TIMER2_COMPB_vect){  // Interrupt service routine to pulse the modulated pin 3
    pulse++;
  if(pulse >= 8) { // change number for number of modulation cycles in a pulse
    pulse =0;
    TCCR2A ^= _BV(COM2B1); // toggle pin 3 enable, turning the pin on and off
  }
}

void setIrModOutput(){  // sets pin 3 going at the IR modulation rate
  pinMode(3, OUTPUT);
  TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20); // Just enable output on Pin 3 and disable it on Pin 11
  TCCR2B = _BV(WGM22) | _BV(CS22);
  OCR2A = 51; // defines the frequency 51 = 38.4 KHz, 54 = 36.2 KHz, 58 = 34 KHz, 62 = 32 KHz
  OCR2B = 26;  // deines the duty cycle - Half the OCR2A value for 50%
  TCCR2B = TCCR2B & 0b00111000 | 0x2; // select a prescale value of 8:1 of the system clock
}

void setup(){
  setIrModOutput();
  TIMSK2 = _BV(OCIE2B); // Output Compare Match B Interrupt Enable
}

void loop(){
// do something here

In the interrupt service routine you can count the number of pulses and change the LED you are toggling after so many.

To detect modulated IR you need an IR receiver. As you only have one receiver then it is simple to look at.

HOWEVER - most IR receivers can only detect a certain number of pulses before the output flags. So you should arrange for a period of non blinking between each change in LED.

TCCR2A = _BV(COM2B1)

Where is the use of "_BV" explained ? Is that in the 328 datasheet ?

@Zeus,
Do you have any code working yet ?

raschemmel:

TCCR2A = _BV(COM2B1)

Where is the use of "_BV" explained ? Is that in the 328 datasheet ?

Yes it is in the data sheet, it is one of the timer T2 variables.

Until now I've been thinking of the project as needing to output the 30KHz pin on multiple pins (one pin at a time). It occurs to me that since you will only be using one at a time, you could connect one side of all the emitters to a common pin which you modulate at 30KHz. You would enable or disable each emitter by connecting the other leg to a separate pin which was configured as an input to disable the emitter, or an output to enable it. That simplifies the requirements for the 30KHz pulse generation.

I still don't see why multiplexing the 30khz signal to the leds has not been discussed.

Thanks for the input everyone.

Peter,

Yes I have a 30KHz receiver so I do not have to worry about the mechanics of that portion, only how to incorporate it into my code.

I was thinking for using two pins per pair of LEDs and taking advantage of the fact that the LEDs are diodes and only run one way, but your idea will sounds like it would simplify the code and possibly the demands on the CPU? How does connecting them to a common node simplify the pulse generation? I can see how it would reduce the size of the code but after that I loose it.

I am still having trouble identifying which functions to employ in order to integrate the receiver code. Right now the plan is to modulate the LEDs (hard code or PWM?) and then I am lost. Do I need PWM running in the background so that I can in parallel scan for the pulse, and then use an interrupt to send the detection signal out? And if I do handle the LEDs with PWM will this also be able to handle a loop which cycles through all 6 LEDs while running in the background and scanning in the foreground?

Grumpy Mike,

Very excited to review your code. It is a bit beyond me right now but I learn by example so this is very helpful, thank you. If I understand you correctly it seems that I should be able to add a counter loop to you code and cycle through my LEDs. My understanding up until now was that this could not be done as it amounted to threading which the Arduinos cannot do, so clearly there is something I am missing here.

Also thanks for the info about the receive needing time between LEDs. I did not realize that the receiver hardware what that sophisticated.

Raschemmel,

I suspect that the code does not compile bacause it is only a portion of my overall program. It compiles when in the body of my larger program. What I should have said is that I was having trouble understanding that particular bit of code, sorry about the confusion. No I have not been able to get it functioning yet. I can get one LED to flash at what I believe is 30KHz but I cannot achieve this with PWM yet. I am getting closer though.

Thanks everyone,

Zeus

Do you want a couple of programs that generate 30khz squarewave ? (50% duty cycle) .
You didn't answer my question about why you think you need PWM as opposed to squarewave (50% duty cycle).
You also didn't address my question about why nobody is talking about multiplexing the leds from a single 30khz signal (of whatever type it turns out you need) . I am willing to give you the programs but not until I get a SITREP (Mil-Speak for SITUATION REPORT) detailing everything you have done in terms of hw software in the format:

  1. wired circuit per THIS schematic (cell phone photo of hand drawn schematic using diagram blocks to represent arduino but including pin numbers for all connected pins.
  2. photo of circuit
  3. Entire code as IDE *.ino file
  4. If possible also post the whole program using code tags (probably too large to do this but you could try)
  5. List of exactly what you have done
    a. Ran test with these parameters
    b Changed these parameters (variables whatever) to these values ) and reran test; Observations:==>[observations]
    c. Made following changes to circuit :==> [changes]
    d. Change code parameters to these and retested with modified circuit rev V-1.1
    e. Upgraded circuit to V-1.2 by changing these components :==>[changes]

If you kept a log like any scientist or engineer normally does all of the above is already in your log.

address my question about why nobody is talking about multiplexing the leds from a single 30khz signal

No one is talking about it because only you think it is important. It is not needed.

Ok. That's good enough.

raschemmel:

TCCR2A = _BV(COM2B1)

Where is the use of "_BV" explained ? Is that in the 328 datasheet ?

You've not come across the bit value macro yet?

I'm still searching the datasheet.

ZeusDashing:
How does connecting them to a common node simplify the pulse generation?

It means that you only need to generate the 30KHz signal on a single pin, which makes the logic to do that simpler. Since you now only need to modulate a single pin, it also opens up the possibility of doing it entirely in hardware.