Go Down

Topic: how to make something time sensitive?? (Read 547 times) previous topic - next topic

AWOL

#15
Apr 21, 2017, 04:31 pm Last Edit: Apr 21, 2017, 04:31 pm by AWOL
How about putting the read of the load sensor in loop(), where it stands a chance of working?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Smajdalf

I agree. But if he insists on doing it wasteful with floats, at least do it correct.
Since ADC conversion is not injective function (more voltages result in the same ADC result) there is no "correct way" to make inverse function - assign single voltage to an ADC result. Difference between 1023 and 1024 is below precision of ADC (1 LSB) and probably way below Vref precision (USB power is 5 +/-0.25V). Dividing by 1023 can result in both 0 and Vref reading - you can get "nice numbers". I am not aware about any real advantages of dividing by 1024.
On 8-bit (i.e. Uno) use "byte" instead of "int" if possible - it is faster and saves resources!

AWOL

Quote
I am not aware about any real advantages of dividing by 1024.
1) it's quicker (the compiler will see to that)
2) it's correct.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Smajdalf

1) it's quicker (the compiler will see to that)
2) it's correct.
1) If you convert ADC result to float you are probably not interested in speed
2) Define "correct". You mean politically correct? Gender correct?
On 8-bit (i.e. Uno) use "byte" instead of "int" if possible - it is faster and saves resources!

AWOL

Correct: right, accurate, true, veracious, exact, precise, unerring, faithful, strict, faultless, flawless, errorless, error-free, perfect, word-perfect, scrupulous, meticulous;

You're welcome.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Smajdalf

#20
Apr 22, 2017, 09:23 am Last Edit: Apr 22, 2017, 09:24 am by Smajdalf
Correct: ... error-free ...
Vref = 5V, Vin = 5V. Then analogRead() returns 1023.
MeasuredVoltage = analogRead()*Vref/1024 = 1023*5/1024 = 4.9951171875
error = |Vin - MeasuredVoltage| = 0.0048828125 > 0

Not error-free -> not correct.
Q.E.D.

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

It was not me who started this pointless argument about "correct" divisor. I think it is quite OT now. But I hate when someone presents "truths" such way. There is little difference between 1023 and 1024 (it depends on definition of "correct"; you failed to provide a useful one). There are much more severe problems with analogRead()*Vref/const construct. Such as stability and accuracy of Vref, speed concerns with using float arithmetic and division when it is not needed etc.
On 8-bit (i.e. Uno) use "byte" instead of "int" if possible - it is faster and saves resources!

AWOL

#21
Apr 22, 2017, 09:26 am Last Edit: Apr 22, 2017, 09:41 am by AWOL
Quote
But I hate when someone presents "truths".
Don't take my word for it then - check the ADC section of the datasheet.
Quote
There is little difference between 1023 and 1024
I don't disagree, but the principle is important
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Smajdalf

Don't take my word for it then - check the ADC section of he datasheet.
Is everything in the Datasheet absolutely correct? There are mistakes, typos etc. in most Datasheets.
Does Datasheet states how to convert ADC reading back to voltage? Not my Datasheet. It states how to convert measured voltage to ADC result. It does not even state how it rounds the result to get integer. As I said before - there is no generally correct way how to make inverse of function that is not injective.
On 8-bit (i.e. Uno) use "byte" instead of "int" if possible - it is faster and saves resources!

AWOL

Quote
Vref = 5V, Vin = 5V. Then analogRead() returns 1023.
MeasuredVoltage = analogRead()*Vref/1024 = 1023*5/1024 = 4.9951171875
error = |Vin - MeasuredVoltage| = 0.0048828125 > 0

Not error-free -> not correct.
Q.E.D.
Not really QED, because you haven't started your assumption that a successive approximation ADC can read up to and including Vref.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

AWOL

Quote
Is everything in the Datasheet absolutely correct? There are mistakes, typos etc. in most Datasheets.
Well, I was using AVRs over ten years ago, so I imagine Atmel have had plenty of time to issue errata sheets.

I could believe the datasheet, or I could believe some random bloke on the Web.

Ooo, lemme think about this one, it's a toughie.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Smajdalf

Not really QED, because you haven't started your assumption that a successive approximation ADC can read up to and including Vref.
Oh sorry. And what values it CAN read? What about 0.0000001V? Result 0V, error 0.0000001V -> not correct by your "definition". Or is 0.0000001V also "unfair"?

Anyway in Voltage Reference description the Datasheet states "Single ended channels that exceed Vref will result in codes close to 0x3FF" so you may measure Vref or even more - you should get 1023 for all such voltages.

But the Datasheet in ADC Conversion result section says "0x000 represents analog ground, and 0x3FF represents the selected reference voltage minus one LSB." It apparently support your claim. But it is clearly not true. In reality 0x000 represents "Some voltage between under 0.5 LSB but high enough the chip survived" and 0x3FF represents "Some voltage over Vref - 1.5 LSB but low enough the chip survived".

I don't disagree, but the principle is important.
Now you quote some mysterious "principle". I guess this "principle" dictates what is "correct". Unless you define those terms you are just dogmatic.
When I convert ADC reading to real voltage (and float) I am probably doing it for human to read. When I convert reference voltage (or voltage close to it) I want to see reference voltage on my display. When I convert 0V I want to see 0V. When I convert "something between" I want to see "something between" with linear relationship if possible. This is my "principle" and vision of "correct way". I don't want to guess if 4.9xxxV is maximal reading or if it is 1 or 2 LSB less. If you want spend memory and processor time to make float to get "nice numbers" and then ruin it for sake of "principle" way under noise and ADC error it is your problem. Why you force it to newbies is mystery for me.
On 8-bit (i.e. Uno) use "byte" instead of "int" if possible - it is faster and saves resources!

avr_fred

Let's stay focused people, please stop with the back and forth, now unrelated to the original topic.

To the OP:

Your understanding of the motor overload function where "if the amperage is above a certain level for a certain amount of time, enable a digital output" - while it "kinda" works in the most simplist terms, it isn't how it's done in actual practice.

The function is really one of "what is the rise in temperature of the motor" and when reaching a certain temperature, generate a fault to stop the motor. In order to properly do this, you also have to take into account both the amount of actual overload and motor cooling, those periods where the motor current is less than maximum.

This function is achieved with simple numeric integration. It is the running sum of the amperage over  time that will properly indicate overload. Depending upon how fast that motor temp can rise would typically set your frequency of updating the running sum, perhaps every second for a small motor, perhaps once a minute for a rather large motor.

First get familiar with millis() function so you can perform calculations based on time and then we can work on integrating the amperage to give you an accurate overload condition.

septillion

@, you ask "what is correct?" 1024 is correct. Because if you assume a perfect ADC dividing by the number of steps (here 1024) will give you the exact LSB. That you can't see the difference in real life due to noise, imperfections etc is irrelevant. Something is correct because of the theory tells you so, not because it's close enough in real life.

And even tough I agree if you do float you don't care about speed (float != decimal point!!!) but even in float divide by 1024 is almost twice as fast as divide by 1023.
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

Smajdalf

@, you ask "what is correct?" 1024 is correct. Because if you assume a perfect ADC dividing by the number of steps (here 1024) will give you the exact LSB.
When I ask "what is correct" I want to know "why do you think 1024 is correct and not another number - 325 for example". If you have ideal ADC and divide its result with number of steps (1024 here) and multiply by Vref you get number which is +/- 1/2 LSB from the measured value. OK, I understand this. But
1) Who told you the AVR's ADC is designed as ideal? If I understand SAR ADC design the easiest way is to make is to return ideal value -1/2 LSB (i.e. 0 represents 0-1 LSB, not (-1/2) - (+1/2) LSB).
2) Why "correct" way is to return number from middle of the interval? Why not from its lower/upper boundary? I can easily think about reasons for all scenarios. Why not some other convenient function - such as divide by 1023 to get 0V resp. Vref from 0 resp. 1023 readings?
On 8-bit (i.e. Uno) use "byte" instead of "int" if possible - it is faster and saves resources!

septillion

1) Nobody told you a ADC is perfect. In fact, it's not. But it's designed to be as close as perfect thus using 1024 steps here.

2a) I didn't say that's incorrect. Upper, lower, middle, they are all correct in there own way. But what they have in common is that you have to divide by the number of steps, not a number that's close.

2b) Now that scenario just is incorrect. Then you just add a ugly non linearity ::) Pick a level in one LSB and stick with it.
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy