Welcome! Log In Create A New Profile

Advanced

adc conversion optimizations tonokip

Posted by jamesdanielv 
adc conversion optimizations tonokip
June 11, 2011 12:54AM
I had issues with implementing a large buffer with atmega 1280 on tonokip, because the firmware kept on pausing, and having various issues. After a bit of troubleshooting it ended up being the adc.

After doing an interrupt setup for adc and placing a trap to prevent adc interrupts while serial was >0, the buffer worked with 64 buffers of 64 char each. I also can sample temp every 0.1seconds and firmware still does not pause.

It makes me think that we have a lot of thinking to do in terms of how we sample ad conversions with tonokip when using atmega and no extruder controller.

By the way tonokip does not seem to use interrupts, except for the serial reading.

It takes ~16ms for analog read to complete, and that is as fast as you want it to happen when using 10bit resolution.

However it takes less than 1us to activate adc, and less than 1us to read adc after it is done with conversion. Conversion can happen outside of cpu control. The interrupt just lets you know the conversion is ready. Just store an int with analog values once adc completed, and refresh it again when a pause happens in serial data (which happens about every 2ms no matter what)

What do people think about implementing the adc interrupt flag, when there is no serial data in tonokip firmware?

Does anyone else find this useful? Thanks.
Re: adc conversion optimizations tonokip
June 11, 2011 01:38AM
Teacup already does something similar to this. It continually samples the ADC inputs in an interrupt loop, and fills a volatile array with the results so any code that wants a reading has instant access to them.


-----------------------------------------------
Wooden Mendel
Teacup Firmware
Re: adc conversion optimizations tonokip
June 11, 2011 03:23AM
yeah. i figured teacup might. I'm rediscovering useful microcode over arduino stuff. but is it not good for tonokip firmware to have something like this? especially because of the fact that you can disable interrupt during serial read and everything is fine.

without disabling interrupt before adc reads the machine goes into a fit and slows way down. there may be a way not to need interrupt use, but it would be a timing headache in arduino ide. also my main interest is increasing the buffer to see if there would be a benefit for buffer compression.

here is how to enable interrupt. keep in mind temp_pin does not change with configuration yet. i will post the firmware when I'm done doing buffer work. i want 128-256 buffers for atmega1280

after some web soul searching this is what was pieced together below:

beginning add this to make it handle bit changes.
*****************************************************************
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
#include
#include
volatile int adcprocessing =0;
boolean analogsampling=true; //if true interupt for adc runs

at beginning of void setup:
*****************************************************************

// defines for setting and clearing register bits
// set prescale to 128
sbi(ADCSRA,ADPS2) ; //slow sample. but its ok!
cbi(ADCSRA,ADPS1) ;
cbi(ADCSRA,ADPS0) ;
//cbi(ADMUX,ADLAR) ; //testing stuff..
ADCSRA = _BV(ADEN) | _BV(ADPS1) | _BV(ADPS0);//redundant but leaving in for now...
ADMUX = (1<Edited 1 time(s). Last edit at 06/11/2011 03:25AM by jamesdanielv.
Re: adc conversion optimizations tonokip
June 11, 2011 08:26AM
I don't know if Tonokip is still being activly developed. Sprinter is active and a devivitive of it. If sprinter doesn't already do out of band interrupt adc it should. Sprinter also has many other improvements too.
Re: adc conversion optimizations tonokip
June 12, 2011 02:57AM
sprinter uses the analogRead(pin) format.
Re: adc conversion optimizations tonokip
June 12, 2011 01:36PM
Guys

The sampling thing you mentioned earlier in this section is Oversampling and Decimation.

Along with some other tricks like low pass filtering (averaging to everyone else) you can do some clever things just by rearranging how you collect together your samples, without getting into the full FIR DSP thing.

[www.actel.com]

Is a fairly good doc that collects together a bunch of useful stuff.

Cheers

aka47


Necessity hopefully becomes the absentee parent of successfully invented children.
Re: adc conversion optimizations tonokip
June 12, 2011 01:45PM
Something with a little more pictures and less reliant on math and relevant to atmel....

[www.atmel.com]


Necessity hopefully becomes the absentee parent of successfully invented children.
Re: adc conversion optimizations tonokip
June 12, 2011 01:59PM
There are a few arguments in favour of using techniques like these to improve the ADC readings.

1. The time constants (or response if you like) of thermistors is very slow compared to the speed of a free running ADC & Interrupt scheme like Teacup uses. We are effectively massively oversampling any way, why not put it to good use ?

2. All RepRap machines and firmware are by virtue of being mechatronic are very noisy (electrical, and sometimes tunefully audible) I guess with the heater control we are also switching high-ish power levels which is again very noisy.

3. We want stable high resolution, accuracy and precision to get good quality heater control. When all of the other gross mechanical issues have been ironed out, fine heater control will be the new frontier for those who want to pursue build quality as an end in itself.

I feel that all of the above is relevant to all of the firmwares not just Teacup. Perhaps arguably more relevant to Soupcup.


Necessity hopefully becomes the absentee parent of successfully invented children.
Re: adc conversion optimizations tonokip
June 12, 2011 10:24PM
Basically if we store the last 64 samples and add them all together (or some more memory-efficient averaging algorithm) we get a lot more usable precision and a drop in noise. I've done those algorithms before, just didn't know how useful it would be for printing since the heater block does quite a bit of thermal averaging all on its own


-----------------------------------------------
Wooden Mendel
Teacup Firmware
Re: adc conversion optimizations tonokip
June 13, 2011 06:49AM
It is more memory efficient to do
average += (sample - average) >> 6;
Similar result to averaging over 64 in terms of how fast it reacts, but it is a simple IIR filter rather than FIR. It takes more notice of recent samples than old ones. Very CPU efficient.

Edited 1 time(s). Last edit at 06/13/2011 07:06AM by nophead.


[www.hydraraptor.blogspot.com]
Re: adc conversion optimizations tonokip
June 13, 2011 09:09AM
Thats quite subtle.

In the past I have used a ring buffer to keep samples in and for each one subtracted the last just taken from the ring buffer from a total (the running average or oversample-total ) and then added the new one to the total before puting it in the ring buffer then copied the total and done the shift for division or decimation. A lot quicker than summing every value on every sample. Using buffer sizes that fall on binary sizes makes a lot of the ops logical and quick, It also gives a fixed number of cycles each turn so is predictable.

I might use the IIR technique some time, that is even more economical although not S&D.

It is interesting that oversampling is efectively averaging as well. It would probably be overkill to average the S&D'd values.


Necessity hopefully becomes the absentee parent of successfully invented children.
Re: adc conversion optimizations tonokip
June 13, 2011 07:19PM
nophead Wrote:
-------------------------------------------------------
> average += (sample - average) >> 6;

I have used this algorithm a few times, and I find that it actually decreases precision massively! If (sample - average) is less than 2^6, each sample produces zero change of the average! Also have to watch out for negative values and bit shifts as they don't interact well. This works well with floating point values and a divide rather than a shift which would save memory but not cpu cycles over other methods.

I like aka47's ringbuffer idea, I can see that working quite well.


-----------------------------------------------
Wooden Mendel
Teacup Firmware
Re: adc conversion optimizations tonokip
June 14, 2011 12:02AM
Any way you guys think it should be done, it is better than it is now.... smiling smiley


For testing the firmware now used is sprinter. I've modified the analogRead samples such as
value =analogRead(temp_pin0) to
Is now an int sample
value=adcprocessing
Processed analog changes every 2ms so whatever the last stored value is what is used. Granted it may be better to only sample when needed, if known in advance, this method is quite efficient especially with a trap that stops Interrupts to adc when serial is running.

ISR(ADC_vect)
{
// Code to be executed when ISR fires
if(analogsampling){ //allow analog sampling?
noInterrupts();

byte low=ADCL;
byte high=ADCH;
adcprocessing=high<<8|low;// lower 8 bits
interrupts();
}



Whatever is done in the end better be fast, probably recommend less samples probably 8

average += (sample - average) >> 3; // IMHO

even though adc conversions are quick when done with the interrupt, the reality is they can only be completed when serial buffer is empty. (no other acting interrupt, the serial interrupt is very time critical.)

Just a quick note. gcode finished simulated (no actual filament used, but mechanical motions and printer used) build run with 64 buffer, sampling temp every 0.1 seconds in repsnapper (a normal no no.). With using sprinter with analogRead, system gets serial errors and eventually does not move. testing on arudino mega 1280 with no etruder controller. Also I have 2 monitors and a mouse also polling on the USB

Edited 3 time(s). Last edit at 06/14/2011 03:44AM by jamesdanielv.
Re: adc conversion optimizations tonokip
June 14, 2011 03:21AM
Actually, what I do is scale up the value first and use a cast to sort out the shift. E.g.. for a ten bit ADC.

    word sample = ADC << 6;
    average += ((short)(sample - average)) >> 3;

I think shifting negative numbers is implementation specific in C, but all the compilers I have used do an arithmetic shift if the operand is signed.

Having said that, with bang-bang control noise doesn't matter and is actually beneficial. I can see it upsetting the D term with PID though. I do have 10uF ceramic on my thermistor leads.


[www.hydraraptor.blogspot.com]
Re: adc conversion optimizations tonokip
June 14, 2011 03:38AM
jamesdanielv Wrote:
-------------------------------------------------------
> even though adc conversions are quick when done
> with the interrupt, the reality is they can only
> be completed when serial buffer is empty. (no
> other acting interrupt, the serial interrupt is
> very time critical.)

Disagree. At 115200 baud and saturated down-link, the serial RX interrupt fires 11520 times per second. We have until the next character is fully received to pull the byte from the hardware buffer, so at 16MHz that gives us over 2700 cycles! Of course we can't wait that long every time, but as long as we can run the RX interrupt every 1380 or so cycles we'll get everything. While it is important that we can satisfy those limits, I would hardly label them as 'time-critical'.

The serial interrupt has a higher priority than the analog interrupt, so as long as neither interrupt runs for a long time they'll both be serviced quickly enough to support 115200 baud without dropping any characters.

Teacup is able to receive TWO serial streams at 115200 AND have an analog interrupt loop running fulltime AND have two timers firing without trouble.


-----------------------------------------------
Wooden Mendel
Teacup Firmware
Re: adc conversion optimizations tonokip
June 14, 2011 04:09AM
yes, but you forget we are also sending serial data.... smiling smiley which by the way i also think is problematic. 1 the processor completely stops until all serial data is sent (arduino22 fixes this with a serial TX buffer, but you are sending and receiving )


Also Atmel is inefficient at call procedures, don't they take 4-5 cycles? and then also the overhead of c interpreter to push and pop (2cycles) complex this by 2 interrupts screaming at each other, when one is done the other one is waiting right?
Atmel command cycles [www.atmel.com]

all this interrupting starts to effect the timing of the steps, not just in 1 cycle ways, but each interrupt causes at least 13-20cycle delays


also even though arduino stores 128 RX buffer further looking into how the serial interrupt is handled specifically by the Atmel micro-controller shows that it actually is a 2 byte buffer, a serial shift register holds one byte, and the next byte is buffered until the shift register handles the serial data. so you usually have about 10.5 bits time to do other tasks before going back to move buffer byte data, or else an entire byte is lost.... serial sending data is worse. 1 byte stored to shift out. i wish the arduino sacrifices 2 more pins to hook up to the FTDI handshaking pins! (CTS,DTR) so no matter what when data is sent by FTDI buffer it is sent at baud speed and does not wait or stop. it is absorbed within a short time, or it is lost!

teacup works OK if you use send.py correct? also i think it adjusts how much data to send into buffer by timing how long it takes for a move to complete and before hand sends the next command. Something i think should be incorporated into rep snapper.


Don't get me wrong. i love teacup. I probably would have used it for my test project, if it were easier to read thru. Sorry simplicity is my vice. Tonokip/splinter are easy to experiment around with. People can learn a lot about teacup and learn a lot from it.

Edited 2 time(s). Last edit at 06/14/2011 04:27AM by jamesdanielv.
Re: adc conversion optimizations tonokip
June 14, 2011 04:31AM
Yup I have always been a little cautious with using logical shifts for arithmetic purposes and stuck to unsigned values. If I needed belts and braces I would logically combine a mask to forcibly set/clear the bits that have been shifted out of as apropriate.

The speed benefits of using logical operators and binary increments/array sizing are so massive that I have used them many times. Particularly when ring buffering.

Sure I agree too much noise will affect the D PID term. Oversampling and Decimation has the unusual property of liking/needing noise on the input samples but the output stream has the noise that was originally needed averaged out of it.

Having said all of that S&D is nowhere near as fast as a fast high resolution ADC with a clean signal.

I think in our case though, the signal is noisy, the ADC is lowish resolution but way fast enough compared to the timed response of the heater circuits to oversample comfortably.

There is a seductive urge to run ADC's flat-out at their fastest speed. Again given the relatively low time constants that our heater circuits exhibit there is an argument that this is potentially several orders of magnitude of overkill.

Indeed as Nopheads successful Bang/Bang control shows the timed response of the heater circuits is slow enough for bang bang control to work sufficiently well.

PID to be used at it's best (I have found to my cost, messing about building egg incubators) is sensitive to the time period between the samples and it's relationship to the timed response of whatever it is controlling.

For example a PID loop running too fast for the response of the controlled heater exhibits greater instability (ie will oscilate whatever values you use to tune your loop) and greater inclination towards Integral windup.

A PID loop running too slow won't respond to changes quick enough.

There is then an optimal timing range or frequency range for doing the PID loop which is related to the timed response of whatever it is controlling

Another useful observation, The PWM modules in the atmega are free running, ie you set a value and it pwms that value forever until you change it or stop it. PID then does'nt need to run anywhere near as fast as the PWM frequency. It can run relatively infrequently so as to nudge the PWM to a better value

Given these arguments there are then some things that can be done to improve performance and reduce interrupt loading and processor cycle usage.

1. Throttle back the ADC sample rates (maybe by ADC clock reduction for example) but not so much that our S&D cannot take place.

2. Use S&D to increase resolution and clean noise.

3. Rather than doing PID calculations every sample. Do PID every X many samples. Where X is less than the number of samples we are oversampling (X as a factor of num samples is good).

Over sampling is perhaps best then done by the ADC interrupt routine. (not a biggy as we have slowed ADC sampling anyway)

Decimation only needs to be done for the oversampled totals we are going to use so is the first step in the actual PID code. Decimation reads from whatever the current Oversampling total is.

The PID code/loop is timed and interruptible therefore decoupled from the Oversampling and ADC collection. If it slips a little in time who cares. As the PWM rate is constant. It is just the update that arrives a little late/early. But not enough to influence the validity of the control loop.

All in all then a scheme like this may make the question of serial or PID and one interfering with the other a little less pressing. Indeed as PID becomes interruptible there is no conflict. It may even leverage a bit more performance from the firmwares.

In reality though I don't actually know enough about the teacup firmware (or any other existing) code to say if these optimizations would be of any value (some or all might have already been done).

Thought for what they are worth.

aka47


Necessity hopefully becomes the absentee parent of successfully invented children.
Re: adc conversion optimizations tonokip
June 14, 2011 04:37AM
jamesdanielv Wrote:
-------------------------------------------------------
> yes, but you forget we are also sending serial
> data.... smiling smiley which by the way i also think is
> problematic. 1 the processor completely stops
> until all serial data is sent (arduino22 fixes
> this with a serial TX buffer, but you are sending
> and receiving )

That's a well known failing of the arduino libraries. Teacup has had a TX queue since first commit, so we've always been able to send and move on, and send from interrupt context.

> also even though arduino stores 128 RX buffer
> further looking into how the serial interrupt is
> handled specifically by the Atmel micro-controller
> shows that it actually is a 2 byte buffer, a
> serial shift register holds one byte, and the next
> byte is buffered until the shift register handles
> the serial data.

That's what I was referring to in my previous post.

> so you usually have about 10.5
> bits time to do other tasks before going back to
> move buffer byte data, or else an entire byte is
> lost....

Not quite, UDRn is overwritten when a new byte is completely received, so we have a hair less than 20 bits worth of time for the first byte received, and 10 bits of time per byte thereafter. This is also what I was referring to in my previous post. 10 bits at 115200 baud is 1388 8/9 cpu cycles, assuming a 16MHz crystal.

If we miss it, then yes the byte is lost, and the OR (overrun) flag is set.

> serial sending data is worse. 1 byte
> stored to shift out.

Yes, but it doesn't matter if we don't push the next byte in time- there's no requirement for us to send all our bytes back to back to the host. We could send one byte every 10 seconds and any sensibly written hostware should behave just fine. Even if we are sending back to back, the timing is the same as RX- 10 bits of time per byte, or ~1388 cycles.

It only takes about 50 cycles to fire the interrupt, massage the buffer and wrangle the serial I/O port, so we have plenty of time to run a bidirectional 115200 baud stream. I have tested this, and I had to boost the baud rate to 500Kbaud before teacup started dropping bytes! That's 320 cycles per byte, and I still had all the other interrupts running.

> i wish the arduino sacrifices
> 2 more pins to hook up to the FTDI handshaking
> pins! (CTS,DTR) so no matter what when data is
> sent by FTDI buffer it is sent at baud speed and
> does not wait or stop. it is absorbed within a
> short time, or it is lost!

Teacup uses XON/XOFF for this. The FTDI has hardware support for XON/XOFF vs its internal 64 byte buffer, so as long as our RX interrupt fires in time we can use the FTDI's buffer as well as our own ram for buffering incoming serial! We can safely assume that the host is plenty fast enough to receive everything we throw at it, so TX flow control isn't implemented.

The FTDI also supports hardware handshaking if you choose to hook it up, there are 4 unused GPIO from the FTDI exposed on all arduino boards that I know of at connector X3. Using these would also depend on our interrupts firing fast enough.

> teacup works OK if you use send.py correct? also i
> think it adjusts how much data to send into buffer
> by timing how long it takes for a move to complete
> and before hand sends the next command. Something
> i think should be incorporated into rep snapper.

yes, teacup works with send.py. It also works with cat myfile.gcode > /dev/arduino if XON/XOFF is enabled winking smiley

The hostware is supposed to wait for an 'ok' before sending the next line, so we only reply with 'ok' when we're able to deal with another line. This is true of all reprap hostware and firmware. I'm not sure why reprap host, replicatorg and repsnapper all have trouble with this, but afaik Sprinter experiences exactly the same difficulties as teacup in this regard.

Kliment's Pronterface should work much better.

> Don't get me wrong. i love teacup. I probably
> would have used it for my test project, if it were
> easier to read thru. Sorry simplicity is my vice.
> Tonokip/splinter are easy to experiment around
> with. People can learn a lot about teacup and
> learn a lot from it.

Different strokes for different folks I suppose, I've heard quite a number swear that teacup is the easiest to read, and quite a few others swear that tonokip (now sprinter) is the easiest. Personally, I can't make any sense of sprinter, but I can navigate teacup with relative ease. I've always had trouble navigating source that's all crammed into one file with proper indentation given an occasional nod, and the theory of one statement per line totally absent. Gnu screen gives me exactly the same sort of headache.


-----------------------------------------------
Wooden Mendel
Teacup Firmware
Re: adc conversion optimizations tonokip
June 14, 2011 04:45AM
> I'm not sure why reprap host, replicatorg and repsnapper all have trouble with this,

I might have found a contributor to this, posted it in the Teacup-Firmware thread of this forum last night.

The host wares are sensitive to the prototocol of commands and responses. Not just the protocol of byte transfer. (gtkterm, file cat etc are only bothered about byte transfer)

In Teacup some of the G-codes execute out of sequence and this may be throwing the host-ware.

I don't think this is the magic bullet, just a contributor to what may well be a compounding of minor incompatibilities at both ends.


Necessity hopefully becomes the absentee parent of successfully invented children.
Re: adc conversion optimizations tonokip
June 14, 2011 04:47AM
aka47 Wrote:
-------------------------------------------------------
> In reality though I don't actually know enough
> about the teacup firmware (or any other existing)
> code to say if these optimizations would be of any
> value (some or all might have already been done).

Teacup has free-running ADCs, but we only check the results occasionally. Each sensor type has its own read period with 10ms granularity, and currently the thermistors are set to read every 250ms, or 4Hz. PID is run once per reading. The clock runs in an interrupt, constructed to give a consistent period regardless of interrupt latency, however the actual temperature readings are done in main loop via a flag set by the clock.

Teacup already implements 8x oversampling but it's only used for calculating the D term in the PID code, and it only uses the last 8 temperature readings rather than the last 8 ADC results.

We could probably gain some advantage from only reading the ADCs when we need to, and make the exact read time more consistent as well. Alternatively, oversampling with the free running ADC interrupt would be neat, although probably not terribly useful for reprap due to heater's thermal time constant.


-----------------------------------------------
Wooden Mendel
Teacup Firmware
Re: adc conversion optimizations tonokip
June 14, 2011 04:56AM
aka47 Wrote:
-------------------------------------------------------
> In Teacup some of the G-codes execute out of
> sequence and this may be throwing the host-ware.

But the 'ok' response is always to the line of g-code just sent so regardless of teacup's buffering, the hostware is receiving the correct response vs its expectation.

For buffered commands, the ok is sent after the move is queued, not when it's dequeued.


-----------------------------------------------
Wooden Mendel
Teacup Firmware
Re: adc conversion optimizations tonokip
June 14, 2011 05:35AM
I think we are missing the point a little, probably I have'nt explained it well.

consider:-

M105
M109 P0 S225
M105

This should in sequence do :-

M105 get the current temperature of the extruder (ambient if from cold)
M109 P0 S225 Heat the extruder up to 225 Deg C and return when at temp.
M105 get the current temperature of the extruder (now reading 225 Degrees C)

What we do get instead is:-

M105 get the current temperature of the extruder (ambient if from cold)
M105 get the current temperature of the extruder (Still same as above)
M109 P0 S225 Heat the extruder up to 225 Deg C and return when at temp.

If we have a bunch of buffered moves going off as well the returns are peppered with random OK's sometimes in the middle of a return string that I am waiting for.

Things like the temperature report, like the position report etc.

If I am a piece of host-ware and I issue a command to tell me where the toll is at ie position request, I should be able to listen for the reply. If that reply is returned to me embedded in and occasionally shot through with OK's I will have difficulty recognizing it.

As a piece of host-ware I now don't know what to do and lock up awaiting a response that will not come because it already came in an unrecognizable format.

This is exactly what is happening.

When I write C code I know what order or Sequence the instructions will execute in. A run through with a debuger confirms this.

In this case the G-code (whilst being predictable if you know what is going off) appears to have an arbitrary execution and responce order.

C code that picks which instructions to execute and self rearanges the order is completely useless.

In this case though the G- code appears to work as the sending tools don't care what order responses come back and are completely blind as to whether the responses make sense.

Host-wares though are trying to be a lot more clever and the randomly unintelligible responses gum them up. When it happens depends on the G-code sequence and speed of response etc. so looks random.


Necessity hopefully becomes the absentee parent of successfully invented children.
Re: adc conversion optimizations tonokip
June 14, 2011 05:41AM
Actually sorry guys the past couple of posts have been heading rapidly off topic.

I have cut and pasted my last to the teacup firmware thread where it is arguably a little more on topic.


Necessity hopefully becomes the absentee parent of successfully invented children.
Re: adc conversion optimizations tonokip
June 14, 2011 06:44AM
aka47 Wrote:
-------------------------------------------------------
> If we have a bunch of buffered moves going off as
> well the returns are peppered with random OK's
> sometimes in the middle of a return string that I
> am waiting for.

Perhaps you're missing what I'm saying. Consider this example:

> M109 S225
> G1 X10
> M114
> G1 Y10
> M114
> M105
> G1 Z10
> M105
> M114

< ok (M109 S225)
< ok (G1 X10)
< ok X:0 Y:0 Z:0 E:0 F:50 (still warming up, M109 is blocking G1 X10 in the queue so no movement has occurred)
< ok (G1 Y10)
< ok X:0 Y:0 Z:0 E:0 F:50
< ok T:83.75
< ok (G1 Z10)
< ok T:88.0
< ok X:0 Y:0 Z:0 E:0 F:50

As you can see, despite us dumping 9 commands all at once without waiting for any OKs (eg copy-pasted into a serial terminal as a block), the 4 queueable items get queued (and an 'ok' is sent when they're queued) and the 5 data query items return the relevant data (starting with an ok). All responses come one after another, in the correct order, and matching perfectly with the commands sent. If you continue issuing M105 and M114, you will see the temperature stabilise at its set point, and then the movements will occur one at a time, exactly as prescribed by the gcode.

Should we send so many queueable commands that the queue fills, we won't receive an ok to anything until a space in the queue is available, then the oks will continue coming in the correct order, still perfectly matching the gcodes sent. In this situation it is possible to overrun the buffer with M105 and other data query commands, because if teacup receives a queueable item and the queue is full, it /must/ sit and wait for a space to become available and demand that the host does the same by not saying 'ok' until the queueable item has been enqueued.

In fact, with XON/XOFF enabled, you could
( cat myfile.gcode > &3 & cat &3 > myresponses.txt; ) 3<>/dev/arduino
or similar and then match the lines in the two files afterwards, and assuming that no serial errors occurred, they would match perfectly. Even if there's only one M114 and it's after 600,000 lines of various other gcodes- both queued and non-queued commands, the matching ok will be the one with position data.

There is no possibility of 'random OKs sometimes in the middle of a return string' - each command gets a single reply straight away, or everything blocks waiting for the queue to empty enough for us to handle another command.

No data is sent out of band, unless you enable debug options. With debug enabled, it is still impossible that you'll get responses cross-polluting, because cross-polluted responses would require us to be sending data from main loop while an interrupt fires and sends more data from within the interrupt. I don't think any debug option causes data to be sent from interrupts.

The host is never confused about which reply goes with which command, unless it has confused itself regardless of teacup's responses.

The resulting action of a command is what gets queued, not the response.

You can throw commands at teacup until the buffer overruns, and the responses will come back in the correct order every time with no cross-pollution of data.

The gcode processor is completely single threaded, serial, whatever terminology you'd like.


If you're seeing data come back all mixed up, there's something wrong with your code.


-----------------------------------------------
Wooden Mendel
Teacup Firmware
Re: adc conversion optimizations tonokip
June 14, 2011 06:51AM
apologies for the thread hi-jack, we're moving it to the teacup thread.


-----------------------------------------------
Wooden Mendel
Teacup Firmware
Re: adc conversion optimizations tonokip
June 14, 2011 08:52AM
Quote
Triffid_Hunter
apologies for the thread hi-jack, we're moving it to the teacup thread.

THANKYOU!

I know many people are passionate for a particular firmware. what is the best tool to use. the one you know best!


This has been a good discussion that hopefully will lead to improved firmware. whatever flavor of it.

Edited 1 time(s). Last edit at 06/14/2011 09:07AM by jamesdanielv.
Re: adc conversion optimizations tonokip
June 17, 2011 07:08AM
does this make sense for anyone?

volatile int adcprocessingt ; //thermocouple heater
volatile int adcprocessingb ; //thermalcouple bed
boolean analogsampling=true; //if 1 interrupt for adc runs //may need to be volatile
boolean toggle_adc;// used to have interrupt switch between adc //may need to be volatile


#ifdef HEATER_USES_THERMISTOR
ISR(ADC_vect)
{
// Code to be executed when ISR fires
if(analogsampling){
noInterrupts();

byte low=ADCL;
byte high=ADCH;

toggle_adc=!toggle_adc ;// change state
if (toggle_adc){
adcprocessingt=high<<8|low;// lower 8 bits //thermister adc
//switch to oposite adc for bed

byte val =11110000|(byte)TEMP_1_PIN ;
ADMUX=ADMUX &val ;// mux now set for proper channel
}else{
adcprocessingb=high<<8|low;// lower 8 bits //table adc
byte val =11110000|(byte)TEMP_0_PIN;
ADMUX=ADMUX &val ;// mux now set for proper channel

}
interrupts();
}
//ADCSRA |= (1<<ADSC); sent wth enable.



}
#endif


adc read is just
tempthermister=analogRead(TEMP_0_PIN); slow way
tempthermister= adcprocessingt ; // new way


tempbed=analogRead(TEMP_1_PIN); slow way
tempbed= adcprocessingb; // new way
Re: adc conversion optimizations tonokip
June 17, 2011 08:08AM
yep that's pretty familiar winking smiley

I wouldn't limit yourself to only two analog inputs, then you can use it as a generic library.

afaik the interrupts are disabled/re-enabled for you automatically by the ISR entry/exit blocks provided by avr-libc, no need to do it yourself unless you want to nest interrupts (dangerous unless done extremely carefully). There's an ISR_NOBLOCK flag you can use if you don't want this done for you.


-----------------------------------------------
Wooden Mendel
Teacup Firmware
Re: adc 10 bits feedback
July 11, 2011 01:11PM
hey guys.. can anyone suggest a way to read 10 bits from the adc.. i,e. i want value of ADCL and ADCH both for higher resolution..

i write it as:
low=ADCL;
high=ADCH;
sample=(ADCH<<2)|(ADCL);

bt i dnt get sample as 10 bit..
Re: adc 10 bits feedback
July 11, 2011 07:28PM
sample = ADC; works for me


-----------------------------------------------
Wooden Mendel
Teacup Firmware
Sorry, only registered users may post in this forum.

Click here to login