Show off your 2020 AVR project - here is one of mine

Go To Last Post
33 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2


Since I am apparently obsessed with the Enigma cipher machine, I decided to make the most minimalist and yet functional Enigma M4 simulator I could think of.  TINY84A running at 1 MHz on a CR2032 battery.  I was very careful with power savings so it essentially sleeps taking only around 150uA when on plus the LED power consumption.  When in soft OFF mode (5 minute timeout), it uses less than 0.1 uA!  I'm using some Kingbrighi HELI2 LED's which produce an amazing amount of light for extremely low current as well.  Bright LED's in this example are only using 157 uA each, giving it an estimated number of runtime hours for a single 25 cent CR2032 at ~240 hours.

 

Not seen in the video is a recently added Morse code mode that will show you the Morse code for any letter entered.  I also added a blinkenlight's mode where you can display various sequences of either random lights, lights moving left and right, etc.  And of course it can encrypt or decrypt Enigma M4 (and thus M3) messages.  These pcb's are oshpark purple, but I'm going to try some other colors too.  The HELI2 LED's are also available in orange, red, yellow, and blue, though they use 50%-100% more current than the amazing green ones.  I've got a TVS diode and a fuse for some circuit protection on the back especially since the CR2032 positive side is exposed.

 

What have you guys been working on lately?

 

https://youtu.be/PVQSm2OKFzc

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wow, what a cool project!

 

Nicely done!

 

JC

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Even 150uA is not that low for modern LEDs.  I tested some cheap blue LEDs that were plenty bright with just a few tens of uA.

http://nerdralph.blogspot.com/20...

The other reason I like blue LEDs is because they all have a relatively high Vf (~2.6V @ 1mA).  Most of my green LEDs are <2V, though I did get a couple with a different chemistry that are closer to 3V.

 

I have no special talents.  I am only passionately curious. - Albert Einstein

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That would take me forever to do, very cool.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks everyone!  Post some stuff you guys are working on even if it isn't finished!

 

ralphd - it is impressive how far LEDs have come!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK then, on this one, the game is where's Wally, but Wally is hiding behind solder bridges.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

cheeky

Ross McKenzie ValuSoft Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

V(R5) == V(R10)

Last Edited: Sun. Oct 18, 2020 - 04:09 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My not so professional attempt at hand soldering an attiny10 on strip board:

Attiny blinky

In action: https://www.youtube.com/watch?v=...

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

I'll contribute this...

 

https://github.com/wrightflyer/S...

 

It's not directly an "AVR project" but I am using an Uno for some of the prototyping and I have a strong feeling that, against all the advice I usually give about not using multiple processors what I will actually do, rather than using multiplexers to expand Teensy 4 pins I will just use a 40 pin AVR to "mop up IO".

 

So far (until I have all the TFT, encoders, joystick and stuff in place) the user interface actually looks like this. It's modelled using "Ctrlr" on Windows which is a great tool for creating CC based interfaces. All the CC numbers under all the controls show which Continuous Controller channels the synth responds to.

 

 

Apart from putting together a synth I'm learning lots of other technologies as I go along like the use of Pure Data (prior to using Ctrlr):

 

 

or the writing of a simulator for ILI9341/Adafruit_GFX so I can work on UI elements without needing to involved the hardware:

 

https://github.com/wrightflyer/S...

 

 

The other day the Teensy based synth running my Teensyduino code played a tune for the very first time:

 

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

 

 

It's still very rough. It's only monophonic so far, polyphony has yet to come and it does not even have last/high/low note priority but you can just about recognise the tune anyway.

 

I spent some of this last weekend trying to add an Arpeggiator as it'll make "trying out stuff" much easier when you can "set and forget" a chord sequence (or even just a single note) to play over and over again while you fiddle with filters, envelopes, LFOs and so on.

 

Even arpeggiators take a lot of research - different ones offer different things so I've tried to pick and implement a common subset.

 

So far my synth looks pretty simple when you look at it in the Teensy Audio design tool:

 

 

but when you start to add polyphony and more functionality it can get pretty mad looking (this is someone else's design):

 

 

Once you've done the "Lego building blocks design" using the modules, a subset of which are shown down the left there, you then have to write all the glue code that configures every aspect of each block and that's where the real "fun" starts!

 

Last Edited: Mon. Oct 19, 2020 - 01:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Cliff
That last picture looks.like a program I used a long time ago called patcher.

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Well the PJRC audio design tool is just a "hacked about" (Paul's words) implementation of the clever technology at: https://nodered.org/docs/

 

Part of the "cleverness" is the way it can move around bezier curve lines that are joining the "nodes" on the objects. Paul Stoffregen at PJRC (the Teensy bloke!) just chose this as his interface for the audio design tool but it's interesting to see in that and also in "Pure Data" this concept of "programming" by placing objects on a canvas then drawing lines to show the path of dataflow.

 

On this page in my Wiki: https://github.com/wrightflyer/S... I show the basics of using Pure Data:

 

https://github.com/wrightflyer/S...

 

 

That's a kind of "hello world" program that prints a random number between 0 and 9 each time the "bang" at the top is clicked. It's a really weird way to "program" stuff but I could see a future where more programming is done like this. I think there's a bricks/objects type of thing like this for programming AVRs in fact...

 

... ah yes, Google says something like:

 

https://tinusaur.org/2017/05/24/...

 

Last Edited: Mon. Oct 19, 2020 - 08:03 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
I could see a future where more programming is done like this.

 

The funny thing is people have thought that visual programming was the future for a long time. I was using Visual Basic and HP-VEE back in 2001. At the time the VEE visual blocks were shown to a customer that wanted a test setup for validating embedded equipment after the sale. The VEE blocks called programs that ran TCL scripts running in a VM on the test machine.

 

https://www.keysight.com/en/pd-1476554-pn-W4000D/vee-pro-932

 

The TCL scripts were what was used for testing during product integration. I am leaving out many ugly details about keeping everything up to date.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ahhh.... the good old days of HP-VEE.

I still know a small project I did to automate Wifi testing back in the very early 2000s.

First it took a couple of weeks to test a little part of a design as you constantly were adjusting Signal generators, spectrum analyzers and power meters.

Our factory testing team at that time did everything in C++ with their own interface.

We as engineering choose to use HP-VEE as we used only HP equipment, so integrating would just be a non issue.

When we finished our test program we tested things in under 2 days, that was a massive time saver.

Also by that time our factory testing department had gotten notice of how quick we did things and changed things to do other measurements as well. So they decide to switch too. But they decided to use Lab-view instead as it seemed to suit them better. After a while it became clear that a lot of things we did were in common, so we had to abandon HP-VEE and start using labview too. That also meant the end of making programs ourselves as we used the test departments code, we now had to ask for features if we needed them as they were very afraid we would ruin their factory program. Still miss having fun with HP-VEE.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Here is one little recent project, an update of the classic Leslie 122/147 amplifier *and* there is an AVR tucked in there 8) It controls bldc motors in order to get rid of the fussy, heavy old induction motors!

Attachment(s): 

Tom Pappano
Tulsa, Oklahoma

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

tpappano wrote:
Here is one little recent project, an update of the classic Leslie 122/147 amplifier *and* there is an AVR tucked in there 8) It controls bldc motors in order to get rid of the fussy, heavy old induction motors!

 

Very nice :) Is that a C3 I see in the background ? I have an A100 + Leslie 145.

 

I presume the acceleration is configurable to match the age of the motors and drive belts you're trying to emulate. What about the audible 'click' when the speed changes ? ;)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My current project is a humble clock radio.   I'm using the Arduino UNO with an ATmega328P as a base.  It has a 320x240 pixel 16M-color parallel-interface TFT screen as a display.   The FM radio is a cheap RDA5807m and the real-time clock is a DS3231 with coin-cell battery. 

 

  It includes an outside temperature sensor (Texas Instruments 18S20 with 20 feet of 30AWG wire-wrap going to a outdoors window) along with a BMP180 barometer/altitude sensor.  Indoors temperature gets read by the temperature sensor on the RTC DS3231.   Being an electronics technican, I've added a INA219 Power Meter that reads the voltage and current at a circuit point.  The current in milliAmps is read across a 0.1 ohm shunt resistor by the 12-bit ADC in the INA219.

 

  The Arduino UNO runs on +5V and the TFT screen module accepts +5V input and has on-board level-shifter 74HC245 chips to make the 3.3v used by the TFT controller.  This means that the mega328P operates the I2C (TWI) bus on +5V.  However all the I2C devices run on 3.3V, which means they expect to have 3.3v as the Vcc of the I2C bus. I'm using a TCA9548A I2C multiplexer to do this level shifting.

 

  The time gets displayed on four digits that occupy most of the TFT screen.   These digits are created by using graphics elements such as filled circles, triangles, and rectangles.  For example, to make a big '7',  first draw a filled equilateral triangle in the foreground color, then a smaller eq triangle in black (the background color).  Finally make a filled rectangle across the top.  This makes two fat lines: one on the top and a diagonal across the middle to create the '7' character.  An '8' is made by four filled circles.  Two circles filled with foreground color on top and bottom and two black colored circles in their centers.

 

  Control is done using an old television IR remote that uses the common NEC protocol.  I've got 10 FM channels preprogrammed for my city and musical taste.  The other buttons control volume, mute, time/date setting, and a function that you'll never find on a store-bought clock radio:  a button that selects the local classical music station for exactly one minute and then switches back to the original station.   This is for those times when your favorite station just won't stop playing really stupid commercials.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Very nice :) Is that a C3 I see in the background ? I have an A100 + Leslie 145.

I presume the acceleration is configurable to match the age of the motors and drive belts you're trying to emulate. What about the audible 'click' when the speed changes ? ;)

Thanks! That is actually a 1939 model “D”, (undergoing restoration) basically the same case as a C3, but has the chorus generator in addition to the main generator. To the left is a ‘56 RT3 and 147, and in my living room is an A100/145 combo and also a 1938 BC 8) The AVR has full control over the ramp up/down of both rotors, and mechanical noise is pretty much eliminated for recording studio use. The other 16 Hammonds are out of camera view 8)

Tom Pappano
Tulsa, Oklahoma

Last Edited: Fri. Oct 23, 2020 - 05:13 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you have a special tool to "punch" the wires onto those connectors?   I seem to remember fussing with a small screwdriver or similar (or whatever was handy), with mixed results.  

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

tpappano wrote:
Very nice :) Is that a C3 I see in the background ? I have an A100 + Leslie 145. I presume the acceleration is configurable to match the age of the motors and drive belts you're trying to emulate. What about the audible 'click' when the speed changes ? ;) Thanks! That is actually a 1939 model “D”, (undergoing restoration) basically the same case as a C3, but has the chorus generator in addition to the main generator. To the left is a ‘56 RT3 and 147, and in my living room is an A100/145 combo and also a 1938 BC 8) The AVR has full control over the ramp up/down of both rotors, and mechanical noise is pretty much eliminated for recording studio use. The other 16 Hammonds are out of camera view 8)

 

We rarely see B3s in the UK, mainly because they don't fit thru our narrow doorways ! I have played a couple of rental examples though. I know they're all the same 'guts' but there's something special about a B3. I'd like to learn more about my A100's history as it has a label inside saying it was specially treated for tropical climates. Hammonds were assembled in the UK from kits of parts, and mine isn't a conversion from 120V/60Hz, so I do wonder where it started life.

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


I've made some more in different colors now:

 

left side going down:

oshpark purple with green LEDs

oshpark "after dark" black with visible traces (clear soldermask) with orange LEDs

yellow pcb with black silkscreen - didn't expect the visible traces but that is what arrived with red LEDs

 

right side going down

black with yellow LEDs

white with blue LEDs

 

All use Kingbright HELI high efficiency low current LEDs - my first units have had their CR2032 in for maybe a month now and it still shows 100% on the pulse load battery tester.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's pretty cool & most excellent.

 

I'm wondering if you should "dip" them in some acrylic, like they use on table tops.  Cover the button heads with a drop of rtv, maybe stick cardboard in the batt slot. Then no chance of a short.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

 

Good thoughts avrcandies.  I've given a little bit of thought to preventing shorts.  I am using a very small 10m PTC and while the battery holder completely exposes the + side to the world, I take the negative side directly to that PTC with a short trace.  (The bottom of F1 in the picture is a direct trace to the negative battery terminal).

 

10ma PTC:

https://www.digikey.com/en/produ...

 

D1 is a TVS diode.  Amazingly imperceptible reverse leakage.

https://www.digikey.com/en/produ...

 

I should have posted a picture of the AVR side of the board too, here is one:

 

 

Last Edited: Sun. Nov 15, 2020 - 02:50 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avrcandies wrote:
I'm wondering if you should "dip" them in some acrylic, ...
relative to electronics manufacturing, there's optically clear epoxy.

avrcandies wrote:
.... like they use on table tops.
NeverWet may be available at the local hardware store.

 


832WC - Water Clear Epoxy - MG Chemicals

Rust-Oleum® NeverWet® - Homeowner

NeverWet Superhydrophobic Coating Products | Hydrophobic Coating & Water Repellent Spray

 

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

 21 WS2812B LEDs

+ 1 RS-485 transceiver

+ 2 tact switches

+ 1 ATtiny4

-----------------------------------------

= a (mostly) fully functional DMX monitor:

 

 

 

Why?  What can I say?  Some people juggle geese.

 

I've a hand-built prototype on perfboard with an m328p for proof of concept/code.  Much ugly.

 

 

 

I haven't spun the above PCB yet.  Possibly never will!  The LED layout isn't quite the way I'd like.  I'd prefer to use something like these, if I could get them in singles or as a 3-digit unit... but the website appears to have vanished and the domain is up for grabs.

 

The fun part was the code.  I crammed quite a bit into 512 bytes of flash.  Assembly language, of course.  Here's an excerpt from the comments:

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;                                                                       ;;;;
;;;; Introduction.                                                         ;;;;
;;;;                                                                       ;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                           ;;
;; This project originated as an exploration of the possibility of           ;;
;; implementing some kind -- any kind -- of DMX512 / DMX512-A (ANSI E1.11)   ;;
;; application on the most resource-constrained member of the AVR family     ;;
;; (the ATtiny4 with 4 I/O pins, 16 8-bit general purpose registers, 32      ;;
;; bytes of SRAM, and 512 bytes of flash), and for not much more of a reason ;;
;; than 'because'.                                                           ;;
;;                                                                           ;;
;; Once it became clear that this was easily possible (say, controlling a    ;;
;; single LED or servo with PWM via DMX at a hard-coded address), it rapidly ;;
;; evolved in an unbounded manner into a software puzzle, attempting to      ;;
;; answer the question:                                                      ;;
;;                                                                           ;;
;;    "How much functionality can be squeezed into 512 bytes of flash?"      ;;
;;                                                                           ;;
;; In fact, it has become more of an exercise in code compression than an    ;;
;; example of good design.  Mating a 33 cent microcontroller with twenty     ;;
;; dollars worth of addressable LEDs is not fiscally sound.  A proper        ;;
;; implementation of this application would choose a micro with the proper   ;;
;; resources for the task:  Enough pins to handle a standard (and much less  ;;
;; expensive) 7-segment LED display matrix, for starters.  One with a UART   ;;
;; would greatly simplify design and coding, and a crystal oscillator or at  ;;
;; least an accurate RC oscillator is a good idea.                           ;;
;;                                                                           ;;
;; The ATtiny104 would be an excellent fit:                                  ;;
;;                                                                           ;;
;;    - 12 GPIO                                                              ;;
;;    - 1KB flash                                                            ;;
;;    - Self-programming flash                                               ;;
;;    - USART module                                                         ;;
;;    - Improved Internal 8MHz RC Oscillator accuracy                        ;;
;;                                                                           ;;
;; With 12 I/O, there would be just enough:                                  ;;
;;                                                                           ;;
;;    - 7 pins for 7-segments                                                ;;
;;    - 3 pins for 3 digits                                                  ;;
;;    - 1 pin for DMX RXD                                                    ;;
;;    - 1 pin for 2 buttons (via ADC resistor network)                       ;;
;;                                                                           ;;
;; Although, this wouldn't permit the use of colour.  A 13th pin would allow ;;
;; the use of the DP to signify 'Address', 'DMX present', etc.  Or 12 pins   ;;
;; could work by blinking the display for 'Address', 'DMX absent', etc.  The ;;
;; extra flash space would make all of this fairly easy.                     ;;
;;                                                                           ;;
;; With the use of Charlieplexing, seven segments could be driven with just  ;;
;; eight I/O, leaving 4 for other purposes.  The DP also could be driven by  ;;
;; using nine I/O, leaving 3 for other purposes.                             ;;
;;                                                                           ;;
;; However, that's not the point of this exercise...                         ;;
;;                                                                           ;;
;; This application implements a simple DMX monitor.  For input, a DMX       ;;
;; universe is connected to DMX_RXD (PB1), and two user buttons are          ;;
;; connected to BUTTON_DN (PB2) and BUTTON_UP (PB3).  Output is via a single ;;
;; pin, LED_DI_BIT (PB0), connected to a string of 21 WS2812B compatible     ;;
;; addressable LEDS, arranged in three seven-segment digits.                 ;;
;;                                                                           ;;
;; DMX is an asynchronous serial protocol, and requires a fairly accurate    ;;
;; system clock for reliable comms.  The ATtiny4 lacks this, having only an  ;;
;; internal RC oscillator, but one which can be user-calibrated.  The app    ;;
;; auto-calibrates against the DMX frame itself, relying on known timing     ;;
;; characteristics.  Calibration is performed on power-up, and repeatedly as ;;
;; serial framing errors and other signal anomalies are detected, as well as ;;
;; any time the display times out after user input.  In this way the user    ;;
;; can force a calibration simply by pressing a button.                      ;;
;;                                                                           ;;
;; The display can show the:                                                 ;;
;;    - selected DMX address in decimal 001 to 512                           ;;
;;    - contents of selected address as:                                     ;;
;;        - the PWM intensity of all 21 segments (white)                     ;;
;;        - a bar graph (using segments)                                     ;;
;;        - a percentage %00 to %99 and %FL                                  ;;
;;        - a decimal value 0 to 255                                         ;;
;;        - a hexadecimal value h00 to hFF                                   ;;
;;    - most recent non-zero alternate start code in hexadecimal n01 to nFF  ;;
;;    - DMX frame rate (FPS) in hexadecimal as 'r00' to 'r7F'                ;;
;;    - current OSCCAL in hexadecimal as 'o00' to 'oFF'                      ;;
;;                                                                           ;;
;; If no alternate start code has been seen since power-up, 'n00' is shown.  ;;
;;                                                                           ;;
;; Each time an alternate start code is received, the display is blinked by  ;;
;; altering its intensity until the next display update, as an indication.   ;;
;; This occurs even if the new alternate start code is the same as the       ;;
;; previous one.  This blinking occurs in every display mode except PWM.     ;;
;;                                                                           ;;
;; The frame rate is only 7-bit, so maximum measurable frame rate is 127     ;;
;; FPS.  Frame rates greater than that will be displayed modulo 128.  The    ;;
;; measurement will be disturbed by button presses, absent DMX, and periodic ;;
;; calibration.  This mode was added to round out a list of 8 data display   ;;
;; modes.  It may one day be replaced with a more useful mode, as might the  ;;
;; display of the current OSCCAL.                                            ;;
;;                                                                           ;;
;; The colour of the display changes as well:                                ;;
;;    - BLUE:   Selected address                                             ;;
;;    - RED:    Contents/data while DMX not present                          ;;
;;    - GREEN:  Contents/data while DMX present                              ;;
;;    - WHITE:  Contents as PWM intensity                                    ;;
;;                                                                           ;;
;; The default state is to show data (contents, start code, OSCCAL, or frame ;;
;; rate).  The address itself can be shown by pressing either button.  The   ;;
;; address will remain visible for about 2 seconds, then the display will    ;;
;; revert to showing data.                                                   ;;
;;                                                                           ;;
;; Changing the selected address can be done by pressing either the 'UP'     ;;
;; or 'DOWN' buttons while the address is already displayed.  That is, the   ;;
;; first press shows the current address, and subsequent presses (before the ;;
;; display reverts to showing data) will change the address.  Changes are    ;;
;; immediate.  The selected address wraps from 512 to 001, and vice versa.   ;;
;;                                                                           ;;
;; Pressing and holding a button will keep the address on the display,       ;;
;; but it does not result in fast-changing the address as experience with    ;;
;; similar devices might make you expect.  That would take too much flash!   ;;
;; Without fast-changing, going from address 001 to address 257 would take   ;;
;; an uncomfortable number of button presses.  As a compromise, the 'DOWN'   ;;
;; button lowers the address by 10, while the UP' button raises it by 1.  In ;;
;; this way, no address is more than about 50 button presses away from any   ;;
;; other address.  Both step sizes are configurable in the .h.               ;;
;;                                                                           ;;
;; The data displayed can be changed by pressing both buttons at the same    ;;
;; time.  The display will cycle through 8 modes: the five different         ;;
;; contents formats, alternate start code, frame rate, and OSCCAL value.     ;;
;;                                                                           ;;
;; Since the ATtiny4 lacks EEPROM or self-programming, the app cannot save   ;;
;; the selected format or the selected address anywhere.  As such, the       ;;
;; selected address will reset to 001 (or whatever has been configured in    ;;
;; the project's .h file), and the selected format will reset to contents as ;;
;; a PWM intensity, whenever the device is power-cycled.  This allows the    ;;
;; default behaviour to be that of a normal lighting fixture, hard-coded to  ;;
;; a specific address.                                                       ;;
;;                                                                           ;;
;; The register used to store the computed frame rate is initialised, but    ;;
;; the register used to accumulate the packet count which leads to it isn't, ;;
;; so FPS will display a meaningless value for the first 4 or so seconds     ;;
;; after DMX is present.  Frame rate computations do not include frames with ;;
;; alternate start codes, only frames with a null start code.                ;;
;;                                                                           ;;
;; Alternate start codes include 0xCC used by RDM (ANSI E1.20), an emerging  ;;
;; protocol which lies atop and co-exists with DMX.  This application        ;;
;; ignores RDM traffic and all other traffic with alternate start codes, but ;;
;; is otherwise compatible with it.                                          ;;
;;                                                                           ;;
;; As alluded to earlier, the ATtiny4 lacks a hardware UART.  As such, the   ;;
;; async receive code is 'bit-banged', as is the DMX start-of-frame break    ;;
;; detection code.                                                           ;;
;;                                                                           ;;
;; It may be interesting to note that this little DMX512 application uses    ;;
;; 15 of the 16 general purpose registers, and a maximum 8 of the 32 bytes   ;;
;; of SRAM for return addresses of rcall instructions and interrupts.  No    ;;
;; other SRAM is used.  The ATtiny4 lacks GPIORn registers, so a handful of  ;;
;; single-bit flags are implemented by exploiting otherwise unused bits in   ;;
;; low special function registers.  However, every single poetic one of the  ;;
;; 512 bytes of flash is spoken for.  Sixteen bytes are used for a lookup    ;;
;; table, with the remaining 248 words used for instructions.                ;;
;;                                                                           ;;
;; Surely any sane reader has already asked the question:  "Why?!"           ;;
;;                                                                           ;;
;; What can I say?  Some people juggle geese.                                ;;
;;                                                                           ;;
;; Previous versions of this code padded unused flash with the more-or-less  ;;
;; pointless string "DMX512-A", or some variation thereupon.  The current    ;;
;; version uses every byte of flash for the application.                     ;;
;;                                                                           ;;
;; This string was included purely for the warm fuzzy feeling of unity it    ;;
;; created in the author, knowing that a DMX512 / DMX512-A compatible        ;;
;; application completely fills the 512 bytes of flash available.  That,     ;;
;; and he couldn't fathom what else to do with the remaining space, having   ;;
;; shaved away as many instructions as possible, and crammed in as much      ;;
;; functionality as he could think of.  At the time.                         ;;
;;                                                                           ;;
;; Previous versions also included a brief all-segments display test with    ;;
;; dimming on power-up, but the current operational feature set consumes     ;;
;; 100% of available flash.                                                  ;;
;;                                                                           ;;
;; As noted in the introduction of those earlier versions, 'That may one day ;;
;; change':                                                                  ;;
;;                                                                           ;;
;;     "An artist never finishes a work, he merely abandons it".             ;;
;;         - Aaron Copland                                                   ;;
;;                                                                           ;;
;; One more note on the, at first glance, excessive documentation:           ;;
;;                                                                           ;;
;;     "If the code isn't important enough to document,                      ;;
;;      throw it away right now." - Phil Koopman                             ;;
;;                                                                           ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Attachment(s): 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


I started my AVR hobby last year.   I played with at Uno3 kit and wrote a CPU simulator.  I wanted to start on hardware a bit this year but that got side-tracked to deal with work-at-home.

My goal hardware project is a switched boost converter.   I did collect a few parts.  Maybe next year.

 

This year, however, I did recently upgrade my CPU simulator to the AVR-0 series (with separated register file separated from the data space).  I also integrated that simulator with spice.  So now I can simulate a switching converter.  Check this.

 

First, the circuit diagram.  I will ask about the circuit as I get closer to putting parts on a pegboard.  I have NPN instead of MOSFET in the circuit, and a resistor to play with limiting.  That is probably not the best.   The B0 node is where I connect the AVR PWM pin and the A0 node is where I connect the ADC.   My chip is a ATmega4809.

 

 

I will use two controller designs: one robust with 90 deg phase margin and 18 db gain margin; one with 45 deg phase margin and smaller gain margin.  Below are the (log) Nichols plot and Bode plot (gain on top, phase on bottom).  The design has a bandwidth of roughly 20 Hz.  The robust controller is 4th order and implemented in state space form.

 

So, as I mentioned I am running this in a simulator.   The simulator allowed me to find that the controller iteration in floating point takes about 1.43 ms running on a 20/6 MHz CPU.  Below is the resulting simulation showing ADC voltage and output voltage.  I'm not getting 12 v out so there is still something to debug.  

 

The above startup response looks consistent with a 20 Hz bandwidth.  I still need to debug.

 

Here is the spice code:

boost5.cir
* boost converter with DAC/ADC i/f to digital simulator

* boost circuit
L1 02 22 330.0uH

Q1 21 11 1 QBC337
RQ 1 0 1.0Ohm 
RS B0 11 50kOhm

D1 22 42 dmod1
C1 42 0 1.0uF
R1 22 21 12.0Ohm

R2 42 61 500.0kOhm
R3 61 0 100.0kOhm

* source
Vi 02 0 DC 5.0v

* load
*RL 42 0 12.0kOhm
RL 42 0 48.0kOhm

* controller
YDAC DAC1 B0 0 simpDAC
YADC ADC1 61 0 simpADC
.measure tran Vout EQN v(42)
.measure tran A0 EQN v(61)

* execution mode
.tran 0.1us 1000.0ms

* models
.model dmod1 D (is=1e-13 bv=50)

.model QBC337 NPN(IS=4.13E-14 NF=0.9822 ISE=3.534E-15 NE=1.35 BF=292.4 IKF=0.9
+                 VAF=145.7 NR=0.982 ISC=1.957E-13 NC=1.3 BR=23.68 IKR=0.1 
+                 VAR=20 RB=60 IRB=0.0002 RBM=8 RE=0.1129 RC=0.25 XTB=0 EG=1.11 
+                 XTI=3 CJE=3.799E-11 VJE=0.6752 MJE=0.3488 TF=5.4E-10 XTF=4 
+                 VTF=4.448 ITF=0.665 PTF=90 CJC=1.355E-11 VJC=0.3523 MJC=0.3831
+                 XCJC=0.455 TR=3E-08 CJS=0 VJS=0.75 MJS=0.333 FC=0.643)

.model simpADC ADC(settlingtime=5ns uppervoltagelimit=5 lowervoltagelimit=0)

.model simpDAC DAC(tr=5e-9 tf=5e-9)

.end
* --- last line ---

and here is the controller code:

#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

static float ypax(float y, float *a, float *x) { return y + (*a)*(*x); }

void __attribute__((noinline))
mul_Ax(uint8_t n, uint8_t q, float *xn, float *a, float *xp) {
  uint8_t ax, px, qx;
  uint8_t i, j;

  ax = 0; px = 0; qx = q + 1;
  for (i = 0; i < n; i++) {
    xn[i] = 0.0;
    for (j = px; j < qx; j++) {
      xn[i] = ypax(xn[i], &a[ax++], &xp[j]);
    }
    if (i > 0) px++;
    if (qx < n) qx++;
  }
}


volatile uint8_t t_cnt = 50;
volatile uint8_t t_rdy = 0;
volatile uint8_t t_err = 0;

ISR(TCB0_INT_vect) {
  TCB0.INTFLAGS = TCB_CAPT_bm;
  t_rdy = 1;
}


#define nc 4
#define qc 3
float av[] = {
  -0.0001256, +0.0214401, +0.0000000, +0.0000000, +0.0000000, -1.2022974, 
  -1.6119438, +0.5018648, +0.0000000, -1.4851728, +0.7586875, -0.4565842, 
  -1.0470269, 
};
float bv[] = {
  -1.1005587, +0.0124358, +0.0120048, +0.0101036, 
};
float cv[] = {
  +0.0003732, -0.0615034, +0.7568580, -0.6506759, 
};

float x1[nc], x2[nc], *xn, *xp;

float y_ss = 2.0;		      /* A0 steady state voltage */
float u_ss = 0.50;		      /* duty cycle operating point guess */

void init() {
  for (uint8_t i = 0; i < nc; i++) {
    x1[i] = 0.0;
  }
  xp = x1;
  xn = x2;
  x1[0] = 2.0;
}

void iter(float ref) {
  uint8_t i, tc;
  float *xt, u, val, err;
  uint16_t res;

  /* read input */
  t_err = 0;
  if ((ADC0.INTFLAGS & ADC_RESRDY_bm) == 0) {
    t_err = 1;
    return;
  }
  res = ADC0.RES;
  val = 5.0*res/1024.0;
  err = ref - val;

  /* control law */
  xt = xn; xp = xn; xn = xt;
  mul_Ax(nc, qc, xn, av, xp);
  for (i = 0; i < nc; i++) xn[i] += bv[i]*err;
  for (u = 0.0, i = 0; i < nc; i++) u += cv[i]*xn[i];

  /* duty cycle: */
  if (u > 1.0) {
    tc = 255;
  } else if (u < 0.0) {
    tc = 0;
  } else {
    tc = (uint8_t)(256*u);
  }
  if (tc > 200) tc = 200;		/* starting out */
  if (tc < 20) tc = 20;			/* starting out */
  t_cnt = tc;

  /* start next voltage read */
  ADC0.COMMAND |= ADC_STCONV_bm;
}


int main(void) {
  /* TCB1 => PA3*/
  TCB1.EVCTRL = 0;
  TCB1.CTRLB = TCB_CNTMODE_PWM8_gc | TCB_CCMPEN_bm;
  TCB1.CCMPL = 255;			/* period = 0.0768 ms */
  TCB1.CCMPH = 50;			/* high-time */
  TCB1.INTCTRL = 0;
  TCB1.CTRLA = TCB_CLKSEL_CLKDIV1_gc | TCB_ENABLE_bm;

  TCB0.EVCTRL = 0;
  TCB0.CTRLB = TCB_CNTMODE_INT_gc;
  TCB0.CCMP = 6660;			/* period = 2 ms */
  TCB0.INTCTRL = TCB_CAPT_bm;
  TCB0.CTRLA = TCB_CLKSEL_CLKDIV1_gc | TCB_ENABLE_bm;

  /* ADC */
  ADC0.CTRLA = ADC_RESSEL_8BIT_gc;
  ADC0.CTRLB = ADC_SAMPNUM_ACC1_gc;
  ADC0.CTRLC = ADC_PRESC_DIV2_gc | ADC_REFSEL_INTREF_gc ;
  ADC0.MUXPOS = ADC_MUXPOS_AIN0_gc;	/* AIN0 = PD0 */
  ADC0.CTRLA |= ADC_ENABLE_bm;

  ADC0.COMMAND |= ADC_STCONV_bm;
  
  init();
  sei();
  
  while (1) {
    if (t_err != 0) {
      /* signal error */
    }
    else if (t_rdy == 1) {
      t_rdy = 0;
      /* 2.0 v set-point at A0 => 12.0 v at Vout */
      iter(y_ss); /* at 20/6 MHz, takes 1.43 ms :( */
    }
  }
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Cool!

MattRW wrote:
I have NPN instead of MOSFET in the circuit, and a resistor to play with limiting.  That is probably not the best.
Still feasible.

MattRW wrote:
The simulator allowed me to find that the controller iteration in floating point takes about 1.43 ms running on a 20/6 MHz CPU.
SMPS PWM usually is 8b or 12b.

There's 16b floating point; likewise for fixed-point.

 

P.S.

Buck instead of boost :

What are the AVR28DA128 AVR32DA128 AVR48DA128 AVR64DA128 ?? | Page 5 | AVR Freaks

 


e2 PowerEdgeTM Economic Energy using Low VCEsat BJT’s (ON Semiconductor)

[page 7]

Pass Element in Buck / Boost converter

[hysteretic instead of PWM]

Fixed-Point Support - avr-gcc - GCC Wiki

Geek Like Me, Too: Fixed Point Math with AVR-GCC

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you expecting a highly dynamic load (or source), with fast transient response?  If not, you can simply vary the duty cycle of the PWM, just like slowly turning a knob up or down.  For a given PWM setting, you will get a measured voltage, you can sample that voltage, say every 5ms...if it is too low readjust the PWM, or too high, adjust in the opposite direction.  Leave a small voltage deadband (several adc counts), where no adjustment is made.   

 

No calculations are needed at all, other than to compare the desired voltage with the actual measured and step the PWM up or down (make sure you go in the proper direction).  If the difference is very large, you can take larger steps, though this is often not needed.  You can be up & running in a few minutes.  

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

avrcandies,

 

I am reading ADC, then adjusting PWM duty cycle based on the error (set-point minus reading).

But I forgot to set TCB1.CCMPH = t_cnt !!!  Holy cow.  Let me fix and re-run.

 

Thanks for catching that!

Matt

 

$ diff cl1.c-old cl1.c
96c96
<   t_cnt = tc;
---
>   //t_cnt = tc;
97a98,100
>   /* update duty cycle */
>   TCB1.CCMPH = tc;
>   

 

EDIT: still not working -- I'll tinker a bit and start another thread for those interested.  I'll start by making simple feedback (P, I or PI) so simpler code.

Last Edited: Wed. Nov 25, 2020 - 05:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Nice project.

 

Not my area, but likely you will want to use a schottky for D1.

If you aren't using one in your model it will change your circuit response.

 

When you get to the point of real world tinkering, you will also likely want a small cap from A0 to ground, to filter out some of the circuit noise for your ADC reading.

That cap can also filter out someof the "sag" in the output, if desired, but that need depends upon your sampling rate and how many times / inductor charge / discharge cycle you wish to monitor the output voltage.

 

JC

 

Edit: Typo

Last Edited: Wed. Nov 25, 2020 - 05:18 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'll start by making simple feedback (P, I or PI) so simpler code

You likely barely need even that, depending on the speed of needed response (input & output).   Will you have large input or transients that need responded to?  Try setting the  OCR to some value (0-255 if 8 bit PWM, etc)---you will get some very steady voltage.  Try another OCR value & you will see another steady voltage.  Now you have 256 different voltages to select from.   If the load is not too demanding, the voltage will remain steady, even if the load changes.  Unlike an analog circuit, you only have 256 possible selections anyhow,  so a high accuracy computation really does little statically.  If Vout seems to be sagging, merely increase it one click or two. A small deadband is helpful to remove chatter, dur eto one setting being slightly too high and the next being slightly too low.  You can dither between 2 selections to create maybe another bit or two of resolution, of needed. How accurate of a Vout do you need? Usually within +/-5%, so it is very easy to maintain.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avrcandies wrote:
If Vout seems to be sagging, merely increase it one click or two. A small deadband is helpful to remove chatter, dur eto one setting being slightly too high and the next being slightly too low.  You can dither between 2 selections to create maybe another bit or two of resolution, of needed. How accurate of a Vout do you need? Usually within +/-5%, so it is very easy to maintain.

That is very similar to the method I use in my solar charge controllers!

 

 

 

Keys to wealth:

Invest for cash flow, not capital gains!

Wealth is attracted, not chased! 

Income is proportional to how many you serve!

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Attiny10 project which generates different 8 bit sounds using 7.8 kHz PWM:  https://youtu.be/H4Y39luhAmY

 

(The media attachment widget is giving an error when trying to link an image or video).