#avr | Logs for 2014-02-16

Back
[16:52:03] <clixxIO_> Good morning Valen
[16:52:11] <clixxIO_> Just arrive at work?
[16:52:19] <Valen> yup
[16:52:23] <Valen> rough trip in
[16:52:35] <Valen> (from the bedroom 2 meters away)
[16:53:28] <clixxIO_> better than the Sydney Roads, but not so bad for a rainy day
[16:53:58] <clixxIO_> do you have any AVR projects you can show?
[17:07:58] * hjohnson is surprised he can't find a decent forum of people building their own boat electronics
[17:08:21] <Casper> I think people are too scared for that
[17:08:42] <clever> hackman: i have looked into some of it
[17:08:57] <clever> i find it insane that a nmea to seatalk adapter can cost over $100
[17:09:42] <clever> http://www.thomasknauf.de/seatalk.htm
[17:10:09] <hjohnson> clever: I'm building the mother of all data translators
[17:10:15] <hjohnson> and related stuff
[17:10:18] <hjohnson> heh
[17:10:25] <clever> i had plans to do the same, converting between 3 protocols
[17:10:45] <clever> but my dad claimed i would blow up the other expensive hardware and refused to let me even test it
[17:10:54] <hjohnson> clever: so my system will do NMEA multiplexing between onboard GPS, 4x NMEA 183 I/O, 1x AIS input, wifi output
[17:11:05] <clever> nice
[17:11:25] <clever> not as much custom junk as i was dealing with
[17:11:26] <hjohnson> it will also monitor the two battery banks, collect/graph weather data (using the boat's instruments and a variety of temperature probes and an onboard barometer)
[17:11:50] <hjohnson> send out periodic telemetry data either via GSM or Iridium satellite, and talk NMEA2000
[17:12:03] <hjohnson> oh, and serve as a below decks instrument repeater/contorl system
[17:12:19] <hjohnson> one of the goals is to be able to be in an extremely isolated area, send out a satellite message, and get back a quick weather report
[17:12:30] <clever> the stuff i was going to work on had 2 gps receivers (because he needed a display both above and below deck)
[17:12:46] <clever> wind speed/direction, water depth, water speed
[17:12:52] <hjohnson> http://gerblook.org/pcb/SGvzRMHzpVymDwEhMWe78o#front
[17:12:53] <clever> auto-tiller
[17:12:57] <hjohnson> that's what the actual project looks like
[17:13:02] <hjohnson> most of the smarts is in firmware
[17:13:16] <clever> but the hardware used 3 different protocols and several nmea transmiters
[17:13:46] <hjohnson> this project involves 12 serial ports. :P
[17:13:58] <clever> softserial or hardserial?
[17:14:06] <hjohnson> hard serial
[17:14:24] <clever> what did you have to use to get 12 hardserial ports?
[17:14:25] <hjohnson> 2 16754 quad UARTs, and then 4 of the onboard USARTs on the atmel
[17:14:32] <clever> ah
[17:14:40] <clever> ive only been using avr's with a single hard uart
[17:14:51] <clever> but ive studied the code of a softuart, and could adapt it to be multiport
[17:15:10] <hjohnson> I've written my own soft UARTs, not hard... but in this case, in combination with the xmega's DMA unit, it makes my life really easy
[17:15:24] <clever> ah
[17:15:39] <clever> most of the softuart i see use a single timer and its irq to poll each bit several times
[17:15:41] <hjohnson> basically, if I want to write out a 35 character NMEA sentence, all I do is just DMA it to the fifo on the uart, and be done with it
[17:15:47] <hjohnson> yeah
[17:15:52] <clever> which would have an issue doing multiple ports, one timer per pin without changes
[17:16:00] <hjohnson> I wrote one in c.. used an input capture and then did that
[17:16:16] <clever> but in theory, you could use pin change interupts and a single shared timer
[17:16:26] <clever> measure the on and off period of each bit
[17:16:33] <clever> and then calculate how many bit times it was in that state
[17:17:10] <clever> multiple output is simpler, PORTD = 0xff; and PORTD=0; you can now transmit to 8 devices at once
[17:17:28] <clever> but dma would make things so much simpler
[17:17:36] <clever> i dont even have DMA on the avr's i use
[17:18:20] <hjohnson> yeah, I'm doing this on an xmega, clocked at 32 MHz, with 128KB of RAM... will be running FreeRTOS on it, so it has a mini operating system too.
[17:18:44] <clever> nice
[17:18:51] <clever> i was thinking of just using a mega168, lol
[17:21:45] <clever> do you think a 168 could handle 2 softserial and a hardserial?
[17:23:21] <hjohnson> clever: I did a project with a 162 that had two USARTs, and a soft serial
[17:24:05] <clever> probly comes down to clock rate, cycles per message, and what percent of the bandwidth is in use
[17:26:40] <Valen> clixxIO_: show in what way?
[17:26:54] <clixxIO_> photo's for example
[17:27:45] <clixxIO_> or maybe a blog page
[17:27:47] <hjohnson> well, USARTs generate 1 interrupt per character
[17:28:26] <clever> the main problem i often ran into, is trying to do printf in an interupt handler
[17:28:31] <clever> the output is blocking
[17:28:40] <clever> so sending 10 characters, means you also loose 10 characters
[17:28:49] <hjohnson> yeah, don't do that
[17:29:00] <clever> but i could redesign the stdout to buffer
[17:29:07] <clever> static FILE mystdout = FDEV_SETUP_STREAM(USART_Transmit, getch,_FDEV_SETUP_RW);
[17:29:15] <clever> just make USART_Transmit buffer the data up
[17:29:25] <clever> but there is still the cpu usage issue
[17:29:32] <hjohnson> yeah, you're writing for bare iron, you don't do stuff like that
[17:29:45] <clever> the better option is to queue the data up into an array
[17:29:51] <clever> and then process it outside of the irq
[17:29:56] <hjohnson> all your interrupt handler should do is either signal to the main loop to send the next character, or copy the next character to the buffer and increment the counter
[17:29:56] <clever> so another irq can buffer more up
[17:30:47] <clever> http://privatepaste.com/f6e0d9f3dc is the latest thing i had to re-write
[17:31:03] <clever> i somehow lost the old source, and had the command parsing without warning
[17:31:33] <Valen> hjohnson: I have my ISR's doing 99% of the work, but then i am an evil programmer
[17:31:34] <Valen> ;->
[17:31:42] <clever> its doing a few strcmp and scanf's in the ISR, but i dont expect very high datarates
[17:31:46] <hjohnson> ISRs should be short and sweet :P
[17:32:04] <hjohnson> I'm using FreeRTOS though so there's a bunch of crap
[17:32:11] <hjohnson> mostly synchronization
[17:32:34] <Valen> hjohnson: I mostly run off battery so my main loop is basically main { sleep }
[17:33:04] <Valen> clixxIO_: http://www.vapourforge.com/jake/temp/counterspin%20manual%20-%20public.pdf
[17:33:04] <clixxIO_> I'm trying to get sleep mode working on my attiny's
[17:33:49] <hjohnson> well, normally sleep would be woken up by an interrupt
[17:33:52] <hjohnson> (I ddpend on that)
[17:34:13] <Valen> hence me doing most of the work in ISR ;->
[17:34:25] <Valen> when the ISR finishes it just falls through the main loop and goes to sleep
[17:34:31] <clixxIO_> I've been developing an Event-Framework for AVR.
[17:34:40] <clever> in my case, some of my ISR's set a bit in a field
[17:34:48] <clever> and then when the sleep() returns, i check for that bit
[17:34:49] <hjohnson> that's what I do
[17:34:53] <Valen> I have massive 32 bit avaraging functions running in the ADC ISR ;->
[17:34:59] <hjohnson> haha
[17:35:14] <hjohnson> well, averaging is cheap if you are averaging a power of 2 samples
[17:35:25] <hjohnson> add them all together, then >> 4 (or whatever
[17:35:28] <Valen> then the timer ISR uses that to adjust power
[17:35:41] <clever> hjohnson: the addition can even be skipped in some cases
[17:36:06] <clever> hjohnson: for example, keep an array of 16 items and a running sum, as you remove items from the end of the ring, also subtract them from the sum
[17:36:09] <Valen> I'm measuring a milivolt signal amid a 10's of milivolt level of noise :-< and there is no physical room to do any of it in analog
[17:36:12] <clixxIO_> is there an interrupt on ADC completion for ADC?
[17:36:20] <Valen> yes
[17:36:21] <hjohnson> clixxIO_: yeah
[17:36:42] <clever> clixxIO_: the datasheets even recomend going into sleep mode to get more accuracy
[17:36:50] <clever> with the main cpu off, there is less high freq noise
[17:36:52] <clixxIO_> so instead of polling, you can just get results back from ADC interrupts?
[17:36:55] <clever> and the adc can wake you when its done
[17:36:59] <Valen> so i have 20x gain turned on, measuring 5ma across a .8 ohm resistor
[17:37:04] <clever> clixxIO_: yep
[17:37:22] <clixxIO_> I will have to try that
[17:37:25] <clever> clixxIO_: the adc can also be set to free-running mode, where it will just forever sample and fire the irq
[17:37:35] <clever> free-running mode is good if you want data at regular intervals
[17:37:35] <clixxIO_> Nice
[17:37:39] <clever> audio or similar
[17:38:39] <Valen> I have 2 chans to sample and measure vbat, so I take an assload of samples, then change the ADC chan, then the timer will start the sampling again
[17:38:41] <clixxIO_> I'd like to add ADC callbacks to this : https://github.com/clixx-io/clixx.io/blob/master/eventframework/timer.cpp
[17:38:44] <hjohnson> well, free running is harder to do do a fixed frequency... on the xmega it's pretty neat, since you can do that with the event system
[17:39:06] <hjohnson> (ie have a timer running, when the timer fires it sends an event to the ADC to start capturing, without taking any CPU time)
[17:39:24] <clever> Valen: i believe once the adc irq fires, you have a couple cycles of time to change the channel, so you can alternate between 2 channels in free-running mode
[17:39:44] <clever> hjohnson: i was thinking of just adjusting the adc clock to set that up
[17:39:56] <clever> but ive not tried it to see what different adc clocks do to things
[17:40:06] <Valen> I'm doing differential and doing vcc measurement, it takes quite a while for it to settle
[17:40:20] <Valen> changing from single to differential is really slow
[17:40:38] <Valen> (they say take one sample and throw it away, they are wrong lol)
[17:41:34] <clever> lol
[17:42:04] <Valen> heres a question
[17:42:17] <clixxIO_> so I'd just need something like an ADCComplete() callback
[17:42:47] <clever> clixxIO_: thats pretty much exactly how the adc ISR works
[17:42:51] <Valen> I need to run some piezo actuators, basically I need to put out 8 chans between 0 and 50 volts, I'm happy to run PWM and an RC network on the output
[17:43:04] <Valen> but yeah, how would you solve this problem?
[17:43:07] <clever> hmmm, i'm also using adc, *looks*
[17:43:37] <clixxIO_> do you have mains? ie step-down?
[17:43:53] <Valen> I can provide the voltage to run it all off with a lab supply
[17:43:55] <clixxIO_> or do you need to step-up from batteries?
[17:44:01] <clever> ah, i see how i'm doing it
[17:44:13] <clever> i tell all of the ds18b20's to do a temp conversion (their adc is slow)
[17:44:25] <clever> then i tell the avr to do its adc
[17:44:28] <clever> then i wait for the ds18b20's with _delay_ms
[17:44:33] <clever> and thats always slower then the avr
[17:44:38] <clever> so they both finish by then
[17:44:47] <clever> no need for an ISR in my setup
[17:45:25] <clever> bbl
[17:45:52] <clixxIO_> Valen: I just built some mosfet boards with mosfets that go to 55v
[17:46:24] <clixxIO_> https://plus.google.com/109366813998920635083/posts/f4etB2AMs8f
[17:46:31] <clixxIO_> that was the prototype.
[17:46:54] <clixxIO_> I'm waiting on the delivery of the final boards from hackvana sometime this week
[17:47:16] <clixxIO_> they are rated to switch 50v
[17:48:04] <clixxIO_> happy to donate some to you for testing
[17:51:12] <Valen> hmm, I might look at an audio amp
[17:51:32] <Valen> probably more controllable though single ended amps seem rare
[17:52:18] <clixxIO_> piezo's are just a type of speaker
[17:52:51] <clixxIO_> but if you want then yes
[17:53:13] <clixxIO_> that's going to be loud at 50v
[17:54:50] <clixxIO_> btw - http://www.jaycar.com.au/productView.asp?ID=XC4232
[18:02:20] * hjohnson still needs to finsih his readLine function
[18:02:36] <hjohnson> I've got readChar, sendChar, and sendLine done
[18:02:44] <hjohnson> turns out readLine is the hardest part :P
[18:04:03] <clixxIO_> what language?
[18:04:25] <clever> hjohnson: did you see my pastebin?
[18:05:04] <clever> oh, but if your using dma, that changes things
[18:13:39] <hjohnson> clever: missed it
[18:13:59] <clever> hjohnson: http://privatepaste.com/f6e0d9f3dc
[18:14:11] <clever> in my case, i append a byte to the buffer each time a byte comes in
[18:14:14] <clever> and check it against \n
[18:14:25] <clever> once i find the \n, i parse it and start over
[18:14:38] <clever> but you have dma, so that complicates things, since your getting it in bulk
[18:14:41] <clever> strtok maybe?
[18:15:24] <hjohnson> clever: in my case, on rx all I can realistically do is do the DMA when a known threshold interrupt is set
[18:15:45] <clever> could you use strtok to read each line?
[18:15:55] <hjohnson> clever: so I set the threshold for, say, 32 bytes, I can only read via DMA when the threshold interrupt is set, else I realistically have to read a byte at a time
[18:16:25] <hjohnson> clever: tht'd be stupid to use on a microcontroller
[18:16:35] <hjohnson> way way too much overhead
[18:16:54] <clever> strtok has too much overhead?
[18:16:58] <hjohnson> clever: yes
[18:17:12] <clever> where is it coming from, the function seems pretty simple to me
[18:17:42] <clever> any issue using it like this? http://privatepaste.com/856d300276
[18:17:50] <hjohnson> clever: it's a generic implementation/function, which means it has a lot of stuff I don't need.
[18:18:22] <hjohnson> in my case, I just read up to the function, so the simple way to do it is check against an XOR with your token as you read each byte in
[18:18:43] <clever> ?
[18:19:07] <hjohnson> if ((newchar ^ token) != 0)
[18:19:10] <hjohnson> takes a single cycle
[18:19:21] <hjohnson> something XORd with itself will result in zero
[18:19:32] <hjohnson> if it doesn't match, then the answer will not be zero. :)
[18:19:41] <clever> that would work for single character commands
[18:19:57] <clever> but i'm dealing with a whole "set" command
[18:19:59] <hjohnson> clever: right, and if I'm reading in the line until \n or something, that's the fast/efficient way of doing it
[18:20:15] <clever> ah
[18:20:25] <clever> i should check the dis-assembly more
[18:20:50] <hjohnson> and the compiler will generally optimize that to two cycles for the xor and the comparison
[18:20:58] <clever> and i have a handy rule in my makefile for just that, 'make main.asm' turns main.c->main.asm
[18:22:12] <clever> http://pastebin.com/DE2kvDPR dang
[18:22:25] <clever> was not expecting it to turn into 140 lines, lol
[18:22:33] <hjohnson> exactly
[18:22:40] <clever> lets see what its doing
[18:22:40] <hjohnson> the string functions are extremely expensive
[18:22:47] <hjohnson> since, well, they're general purpose
[18:22:51] <clever> is it even inlining the string function, or just calling it
[18:23:00] <hjohnson> usually just calling it
[18:23:02] <hjohnson> they're complex functions
[18:23:10] <clever> so that 140 lines doesnt even include that
[18:23:41] <clever> lets see, 12 instructions in the prologue, not much control over that
[18:23:45] <clever> enless i remove some local variables
[18:23:47] <clever> *looks*
[18:24:03] <clever> ah yeah, this is already the trimmed down one
[18:24:37] <clever> ~6 instructions to call strtok_r
[18:25:08] <clever> why does it need another 5 to call strcmp_P?
[18:25:25] <clever> lines 26 thru 30 of the pastebin
[18:26:14] <hjohnson> clever: exactly
[18:26:26] <clever> hmmm, 28/29 appear to be loading the high and low byte of a flash address, i forget, can the avr load a 16bit value in a single cycle?
[18:27:17] <hjohnson> clever: you are writing for extremely small platforms
[18:27:24] <hjohnson> you can't treat it like a general purpose computer
[18:27:26] <clever> just a mega168
[18:27:34] <clever> 1k of ram, 16k of flash
[18:27:38] <hjohnson> yep
[18:27:45] <clever> ive already reduced the .data section as far as possible
[18:27:50] <clever> i had half a dozen strings in it
[18:28:11] <clever> 'readelf -x .data a.out' works great for that
[18:28:43] <hjohnson> basically you need to start using little tricks and optimizations to make things efficient
[18:29:01] <hjohnson> for example bar = foo/4;
[18:29:05] <clever> that function isnt called as often, so its less major
[18:29:10] <hjohnson> that would generate a huge amount of code
[18:29:14] <clever> and i would expect the compiler to change /4 into a shift
[18:29:18] <hjohnson> since it's doing a divide
[18:29:20] <hjohnson> clever: it doesn't
[18:29:25] <clever> ah
[18:29:34] <clever> let me get one of the more important functions dumped
[18:30:38] <clever> http://pastebin.com/8AJ32HEd
[18:30:53] <clever> why the heck is it pushing so much onto the stack? lol
[18:31:35] <clever> let me remove some local variables
[18:31:46] <hjohnson> clever: because you're calling other functions from within the ISR
[18:31:50] <hjohnson> calls within ISRs are expensive
[18:32:10] <hjohnson> since it has to push everything that the called functions also use
[18:32:35] <clever> how does it know what the called function will use?
[18:32:43] <clever> shouldnt the one being called handle that itself?
[18:32:52] <clever> except for arguments and retval
[18:33:24] <clever> thats part of why i moved it into its own function
[18:33:29] <hjohnson> maybe, I don't remember these intricacies...
[18:33:32] <clever> so it wont allocate those locals on the stack until they are required
[18:33:33] <hjohnson> tbh
[18:33:45] <clever> lets see what its doing with r18
[18:33:56] <hjohnson> yeah, but that still violates the short and sweet mantra for ISR
[18:34:07] <clever> the isr never uses r18
[18:34:25] <clever> the parse command does
[18:34:32] <clever> so parse should be backing up r18, not the isr
[18:35:24] <clever> i think its part of the vaarg stuff
[18:35:42] <hjohnson> clever: right, but you're making a function call
[18:35:48] <clever> i'll have to look at rewriting it to just set a bitfield
[18:35:52] <clever> and do the function call from main
[18:35:56] <hjohnson> r18-r27 can be clobbered by a function
[18:36:09] <hjohnson> but the function won't save r18-r27, becaue it assumes they can be clobbered
[18:36:26] <clever> seems a bit backwards to me
[18:36:28] <hjohnson> so the ISR has to save r18-r27
[18:36:31] <hjohnson> no, it makes sense
[18:36:32] <clever> doesnt x86 go the other way?
[18:36:39] <clever> every function will restore the state before it returns
[18:36:50] <hjohnson> normally, in a function call, the compiler can do whatever it wants with r18-r27 without saving it to the stack on a function call
[18:36:50] <clever> and only the return value register is modified
[18:37:02] <hjohnson> clever: not for r18-r27
[18:37:06] <clever> ah
[18:37:15] <hjohnson> so to make the code re-entrant, the ISR has to save those registers.
[18:37:21] <hjohnson> if you make a function call
[18:37:56] <clever> if possible, i would want to defer that right up until i'm about to make the call
[18:38:01] <clever> but the compiler has no way of knowing that
[18:38:08] <clever> or that the irs isnt re-entrant
[18:39:21] <hjohnson> yeah, this is why you avoid function calls within an ISR
[18:39:30] <hjohnson> if you don't make afunction call, it won't save those registers
[18:39:40] <hjohnson> crap, huge amount of water leaked in under my door
[18:39:51] <clever> ive got the oposite problem
[18:39:56] <clever> huge ammount of 'water' outside the door
[18:40:00] <clever> the snow is past my knees
[18:42:02] <hjohnson> clever: heh.. organization I work with has had 36" of snow in the psat 4 days... they're now up to 50+ inches on the ground
[18:42:15] <hjohnson> but that's expected and wanted... they were looking at record low snowfall until last week
[18:42:33] <clever> i had 2 snow storms in a row
[18:42:39] <clever> and the snow blower wont start now
[18:42:49] <clever> the starter spins freely, its not engaging
[18:42:55] <Tom_itx> fix it
[18:43:09] <clever> its bloody cold out :P
[18:43:12] <Tom_itx> so?
[18:43:22] <Tom_itx> i had to weld the tines on mine
[18:43:36] <clever> i'm not sure if its the solenoid or the teeth broken off
[18:43:43] <hjohnson> http://forecast.weather.gov/MapClick.php?lat=48.19894360832075&lon=-120.77348324138643#.UwFXLUJdVhG there's the 7 day forecast
[18:43:45] <clever> it was initialy making a lot of noise
[18:43:52] <Tom_itx> broken teeth
[18:43:58] <clever> thats what i thought
[18:44:02] <hjohnson> the starter is turning over, then it's the tetth
[18:44:04] <hjohnson> teeth
[18:44:06] <clever> but the 2nd time i tried it, there was almost no noise
[18:44:08] <Tom_itx> due to a broken solonoid
[18:44:09] <clever> it just spun
[18:44:24] <Tom_itx> get out the rope
[18:44:28] <clever> the pull rope was useless
[18:44:38] <clever> and the ice on the floor doesnt help
[18:44:48] * hjohnson idly wonders if he could ever start his boat with the hand crank
[18:44:55] <hjohnson> don't think so...
[18:45:04] <hjohnson> it's a little one lung diesel, no glowplugs
[18:45:13] <hjohnson> starting that with a crank handle would be a huge bitch
[18:49:37] <clever> hjohnson: i removed the call, its still doing it
[18:49:49] <clever> oh wait
[18:49:54] <clever> i forgot, i'm also calling getch
[18:50:31] <clever> should probly inline something that simple
[18:51:15] <clever> (facepalm)
[18:51:26] <clever> even with the inline keyword, it just makes it a normal function in the same .asm
[18:55:08] <clever> had to do -O2 to make it even inline it
[18:56:38] <Valen> hjohnson: i saw jamie from mythbusters talking about hand cranking an engine
[18:56:51] <Valen> take a look and see if you can find a breather port or something
[18:56:58] <clever> Valen: they also did a video once about an electric boat motor
[18:57:02] <Valen> so you can spin the engine up unloaded then hit the button
[18:58:18] <Valen> (hint, find it now, before you need it lol)
[18:58:23] <Valen> decompression valve
[18:59:53] <clever> hjohnson: ok, it now works without any calls in the ISR, but its single buffered
[19:00:04] <clever> so if main is processing the string, the isr cant append to a new buffer
[19:19:45] <clixxIO_> reminds me I gotta put a starter-motor on my new engine
[19:20:58] <clixxIO_> I had to upgrade my transistor board with some Diodes
[19:21:12] <clixxIO_> This is reading timing pulses on my arduino - https://plus.google.com/109366813998920635083/posts/Wh1ZMWAnAud
[19:21:35] <clixxIO_> but I didn't have it 'Positive clamped'
[19:25:45] <clixxIO_> so the transistors didn't last as long as they could have. But all fixed now
[19:35:49] <clever> crap
[19:36:00] <clever> the 750ms delay from reading the sensors makes my single buffer problem worse
[19:36:16] <clever> during that 0.75 second window, it can only receive a single line, then it goes nuts
[19:36:27] <clever> really needs double or tripple buffers