Weird pulse train generation on 8 bit AVR - Page 1
Forum section: electronics / general

author: romhunter
author_rank: Regular Contributor
timestamp: May 07, 2018, 06:26:14 pm
content: Long story short, I'm working as an intern. An engineer in my company took off with our company assets, in which there was a piece of source code. It basically is a pulse generator with overcurrent/voltage protection, receive number through UART, oscillator output and stuff like that. The problem is I have to rewrite that firmware by myself, without help (cause others guys is busy working on bigger project), and I can't even begin to imagine how can they generate this type of pulse using an AVR? (ATMega8 to be more precise)So, all and all, can someone help me with this problem? I have to redesign using the same microcontroller (ATMega8) due to its popularity over here. I have attached the crude output pulse below. There're 3 adjustable parameter. The pulse is a square wave with 35us on time

author: metrologist
author_rank: Super Contributor
timestamp: May 07, 2018, 07:01:10 pm
content: what are the adjustable parameters? Pulse period, width, number of pulses, etc?I have code that can generate any pulse pattern on atmega8, I think up to 8MHz.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: May 07, 2018, 07:48:51 pm
content: 1. Is the AVR doing anythingelse?Or is it dedicated to this?Namely, should be pulsing be continuous, or can it be interrupted when a number is received?2. The details of the V/I protection, depend on the circuit. Can the analog comparator be used? Is there external hardware (comparators, or more in-depth stuff)?FWIW, AVR is kind of slow for protection purposes, and I would prefer an analog solution here (assuming the application is something roughly SMPS related). Something equally cheap, but faster, would do a fine job -- like an LPC or STM32 family part.3. The most typical approach, is to use the timer-counters. If the duty cycle is 50%, then a free-running oscillator setting can be used. Set the interrupt to trigger on every overflow, and in the interrupt, count (in a static variable) the number of overflows (half cycles). If the duty cycle is different, you can alternate MAX_COUNT every interrupt, or use a one-shot timer (restart the timer on every interrupt), or use the compare register.In all cases, when the count variable reaches the correct number of cycles, disable the output, set a new MAX_COUNT and reset the interrupt count. Use this to time the off duration.The periodic interrupt can also be used to drive other things in the system, that need periodic sampling. In that case, you'd want to keep MAX_COUNT constant, and use the different compare and WGM modes to get the output right. This may restrict how precisely the waveform can be timed, say if the off duration needs to be a non-integer multiple of the pulse period. You could cheat this by shaving a few LSBs here or there on MAX_COUNT, as long as the periodic-sampled system doesn't mind a minor tweak to its timing. Or if throwing in a runt count is okay, then, sure, that too!Doing the timing with interrupts and timers, should be pretty robust, and you can just read in the COUNT settings from some state variables (note: use atomic reads!). Update the variables from a received serial transaction (which can be polled in the main() loop, or also interrupt driven, to a buffer and such), and the transition should be pretty seamless. Or you can set a flag to reset the count state, or whatever you like.Aside: "all and all", does that count as an eggcorn? (Correct phrase is "all in all", but it's interesting to see phrases evolve. Look up "eggcorn", it's an amusing quirk of language.)Tim

author: romhunter
author_rank: Regular Contributor
timestamp: May 08, 2018, 03:07:24 am
content: Quote from: metrologist on May 07, 2018, 07:01:10 pmThe adjustable parameters is the trigger frequency (a.k.a F, the frequency between 2 pulse), pulse duration D (there will be output pulse for this duration) and stop duration S (no output pulse in this duration). I don't know about those weird name, taken straight from the rewritten document

author: romhunter
author_rank: Regular Contributor
timestamp: May 08, 2018, 03:28:10 am
content: Quote from: T3sl4co1l on May 07, 2018, 07:48:51 pmThe pulse should be continous, and the number (which come from another board) should change the pulse train. A few ADC interrupt will be triggered and an UART might be triggered when the pulse came out. The problem is I have to deal with all those interrupt and the output pulse must remain the same (actually the P and S of my pulse is allowed to have error up to 10ms). GeezThe V/I protection is an opamp connect to INT0, no worries thereQuote from: T3sl4co1l on May 07, 2018, 07:48:51 pmsomehow this fly over my head a bit, I'll re-read it a few times and try to get it. Thanks Tim.

author: Nominal Animal
author_rank: Super Contributor
timestamp: May 08, 2018, 08:41:54 am
content: Quote from: romhunter on May 07, 2018, 06:26:14 pmTherangeand desiredprecisionof the parameters are quite important! What are they?You should probably start by finding out the design requirements.Atmega8's Timer1 can support 16-bit PWM output. At 8 MHz clock, 35 µs is 280 cycles, and the frequency is8000000/(p×n)Hz wherenis an integer between 281 and 65536, inclusive, andpis 1, 8, 64, 256, or 1024. Timer2 supports 8-bit PWM output, and can be clocked from a 32768 Hz crystal for accuracy. Both support interrupts. I think I'd start with a prototype where the pulse train is generated by Timer1, but controlled in software from Timer2 interrupts. (You could also use separate pins for their output, and use two transistors to construct a NAND gate for their combined output. Then, Timer1 controls the individual pulses, and Timer2 the pulse sets.) The 32768 Hz crystal is needed to provide an accurate reference.

author: romhunter
author_rank: Regular Contributor
timestamp: May 08, 2018, 09:16:24 am
content: Quote from: Nominal Animal on May 08, 2018, 08:41:54 amI forgot to add them.F: range from 15-400Hz, with 5Hz step (almost always spot on, sometime have a bit error)D: from 5-100ms, with 5ms step (have about 1-2ms error)S: from 0 to 100ms, 1ms step (this parameter have some error, I have measure its error to be around 3-5ms)S seems to have the biggest error of them all