More members will see your code if posted properly. Read the how to use this forum-please read sticky to see how to properly post code. Remove useless white space and format the code with the IDE autoformat tool (crtl-t or Tools, Auto Format) before posting code. If the code is too large to post it can be attached. Better yet, make a minimal verifiable program that shows the problem.
I use MC3486 along with it and trying to count the rotation.
Please post a circuit diagram of what you are doing?
I modified the given script to handle Z input.
Please post your code.
I am trying to read the voltage on A0 on a particular angle.
But when i rotate it with attaching a motor on approx 1500RPM , its not giving proper values.
Depending on the meaning of "2500 PPR" the encoder may have 10000 quadrature counts per revolution. Your code only reads half of them, but at 1500 rpm your counts are still very high and the Arduino may not be fast enough.
You are not reading the counter variable in a critical section, so it will get garbled occasionally when
you get an interrupt between reading it's two bytes. The Mega2560 is an 8-bit machine so 16 bit
ints are read in two steps.
A critical section is a code fragment with interrupts turned off:
noInterrupts() ;
int counter_copy = counter ;
interrupts ();
Only disable interrupts for the minimum time necessary, use you local copy which is an
intact snapshot of the counter variable.
Interrupt handling has overhead of several microseconds, so there's a maximum count rate you
can achieve without using a hardware quadrature decoder.
First of all, I am sorry for not following the guidelines properly, and thanks for the help and let me understand how to use the forum.
I am posting here the schematic which I tried with and without 74HC14 but no luck.
It's missing the zero point on high rpm.
I have tried various libraries but it not seems working. my ultimate goal is to read A0 value on high speed along with the encoder angle. any help will be highly appreciated. It would be good if I can monitor it on serial.
my ultimate goal is to read A0 value on high speed along with the encoder angle.
What is connected to A0 and what is the samplingRef?
It's missing the zero point on high rpm.
This is the first thing to sort out, as it is a simple interrupt, independent of the encoder reading.
Use pinMode INPUT_PULLUP explicitly for the pin, and make the MODE RISING or FALLING instead of CHANGE so that you only pick up one edge of the pulse.
The library you have selected for the encoder reading is not the best, and uses digitalRead() which will make it slower than other libraries or coding the reading yourself, which would be my recommendation.
First order of business is to get the Z axis pulse reliable, then work on encoder position. Finally integrate the mysterious A() reading. Be aware that the standard analogRead() is slow (~110us) and may create issues with fast interrupts.
I also tried, to change the interrupt orders, like I catch up with the Z first, but in that case, nothing works. Also tried some other libraries.
I have no issue in changing the encoder, as the ultimate goal is to read the voltage from A0 along with the Angle(position) on approx 1500RPM spinning motor.
I use the following code and its working fine if I rotate the encoder manually (by hand). after 360 degrees it will give turn the counter zero with the message in the z interrupt. As there is much serial.print in the main loop. I thought that might causing issues in reading so I change the code to the above. but I need these values on the monitor also. when below code did not worked on high rpm then i change it to the above-posted one.
is there any other encoder or I change the board from mega to due? or software change can help. I am not sure.
You should definitely use a much higher baud rate. Certainly 115200 at a minimum. Depending on the TTL/USB converter on the Mega you might be able to use significantly higher rates which the Serial monitor lets you select.
I do not have a z axis encoder to test with so I can not really evaluate what you have.
I tried almost every baud rate, especially 57600 and 115200.
yes, I am thinking to move on Arduino Due or Teensy 4.0, but never worked on Teensy so not sure how much is it different.
I have seen a youtube video in which 74HC14 is used along with OLED to achieve what I need but there are some different components also used. I did not find that detail.
Anyways thank you for the support. If still you find something which can help, please do share.
Thanks
If still you find something which can help, please do share.
One last thing to look at is speeding up the analogRead().
Here's the link to Nick Gammon's excellent tutorial
As explained in the tutorial, it would be worth a try to take the clock prescaler from 128 to 16 to see if that helps the performance at the higher rpm.
Hi, cattledog,
I tried the code from nick Gammons tutorial. But majorly I don't understand what's going on there :).
but I managed to adjust it with my code. now performance a little better, but it's giving very random values. like if the pin is floating then it gives the maximum volt
I tried both the way by putting it in interrupt as well as the main loop, giving same result. any idea?
Since you have a 50 ms delay in your code it makes no sense to perform the analogRead() in the interrupt. You only get the last value anyway, before the display in loop.
I understand that you are trying to time the analogRead() to occur at the time that the last encoder position is updated, but would think that doing the reading in loop is likely to be very close the value at the reported position.
It's not clear from you code what you actually do with "weight".
Floating point math on the 8 bit classic AVR's is quite slow as there is no hardware support. Converting floating point operations to integer operations by scaling number up is often used to speed things up. Your floating point division of analogRead() by sampling ref would be a good candidate.
There are plenty of online references to reducing floating point operations with Arduinos.
I have made many changes, and seems closer but if you check out the code on your given link under the following header.
Read without blocking
The library function analogRead "blocks", that is, it waits until the conversion is done. However you don't have to do that. This simple code below starts conversion and then checks in the main loop if it is finished. When it is finished it displays the result:
It gives output something like this on serial monitor, if I only execute that code.
Its not analogRead() now, It's reading voltages from A0 by using the following code.
If A0 remains float( without connecting with supply or voltages) its giving those values. these are the ADC values. but why it is so random.
const byte adcPin = 0; // A0
bool working;
void setup ()
{
Serial.begin (115200);
Serial.println ();
ADCSRA = bit (ADEN); // turn ADC on
ADCSRA |= bit (ADPS0) | bit (ADPS1) | bit (ADPS2); // Prescaler of 128
ADMUX = bit (REFS0) | (adcPin & 0x07); // AVcc
} // end of setup
void loop ()
{
if (!working)
{
bitSet (ADCSRA, ADSC); // start a conversion
working = true;
}
// the ADC clears the bit when done
if (bit_is_clear(ADCSRA, ADSC))
{
int value = ADC; // read result
working = false;
Serial.println (value);
delay (500);
}
} // end of loop
Floating input pins are aerials sensing the nearby voltages very sensitively. Usually the stray electric fields in
the environment are mainly mains-derived at 10 to 40V in amplitude, plus any nearby pins switching
between 0V and 5V.
Electrically they are "flapping in the breeze" to steal an expression from Dave at EEVblog!