Go Down

Topic: (Solved)Steppermotor and serial.print and read combined (Read 20399 times) previous topic - next topic

backbone

Never to old to learn and I learn every day

backbone

Ok result of the timing code.  :smiley-roll:
I took 5 seperate reading
4294958292
4294958260
4294958222
4294958264
4294958238
Never to old to learn and I learn every day

backbone

For WIldbill,

Tried 115200bps not working
57600bps no problem.................!?
Never to old to learn and I learn every day

Robin2

#33
May 27, 2014, 10:03 pm Last Edit: May 27, 2014, 10:08 pm by Robin2 Reason: 1

Ok result of the timing code


Something is wrong. Those numbers are far too big.

The Serial.println shoud be (endMillis - startMillis)  - sorry.

From the video the motor seems to be moving properly, just slowly.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

backbone

New values:   :-)
9038
9004
9032
9069
9001

Paco
Never to old to learn and I learn every day

Robin2

They are the sort of numbers I was expecting based on the huge numbers.

Assuming that is for 100 scale.read()s it means that each one takes about 90 millisecs- which seems incredibly slow.

Change the 100 to 500 just to confirm that 90 msecs per read is correct - I don't expect any change.

I have no idea whether other code could read the scale more quickly. I suspect the library may be averaging several analogRead()s and maybe fewer reads would be sufficient for your purposes. That would either require modifying the library or writing your own code. Have you a link to where you got the library?

If there is no alternative to lengthy reads of the scale you have two options - put up with a slow stepper or don't read the scale between every single step.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

backbone

Robin,

https://github.com/bogde/HX711 for the lib
As far as I know I just read each and single value. There is an average option in the lib but I do not use that on purpose.

With 500 reading the value is 45296

Thanks, Paco

Never to old to learn and I learn every day

backbone

Got an answer from the lib designer.

i'm sorry but the library was not written with speed in mind, as that wasn't a concern for me at that time.
i guess one easier way to speed it up would be to use https://code.google.com/p/digitalwritefast/ and replace the slow calls in the read() function with their faster counterparts.

Paco
Never to old to learn and I learn every day

Robin2

#38
May 28, 2014, 11:05 pm Last Edit: May 29, 2014, 10:33 am by Robin2 Reason: 1
I will have a look at the library and what options there might be tomorrow - too late now.
-------
I have now downloaded the library and the PDF datasheet that is linked to by the author.

The Library code seems reasonably straightforward and there is a very short C example in the datasheet.

It should be relatvely simple to write your own code to read the device and then you can check for yourself what is the shortest time to do a single reading. The library uses the function bitWrite() which is going to be an awful lot slower than the simple << shift that is in the code in the datasheet.

The datasheet does say that the device can produce either 10 or 80 samples per second. Neither of those is fast by stepper motor standards and that might be the root of the problem. As far as I can see the library waits until the scale is ready rather than quickly returning with a not_ready indicator. That would be easy to change, but it won't give you more samples per second.

Maybe you need a different device to read the load at more frequent intervals?

Perhaps you should be one doing all the reading ?????

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

backbone

#39
May 29, 2014, 02:49 pm Last Edit: May 29, 2014, 08:15 pm by backbone Reason: 1
Hi Robin,

Thanks for the checking and the info.
With 10 samples per second for the loadcell value I am already happy.
If the motor steps the 1 mm in 1 second.
That would give me 10 samples for 1 mm.
So a sample per 0,1mm in the ideal world without delays :-)
If I raise the HX711 to 80 samples it would give me a sample per 0,08mm.
But a tolerance of 0.1 mm to start the real measurement of the data to the PC is acceptable.

For my application I only need the raw data with 128 or 64 amplification.
So need for average, tare or what ever just the raw data.
I know in these two cases the HX711 needs 25 or 27 pulses when the ADO is low and then the data is in the ADO should be high again.
Currently the pulses come and the data is written  from an analog port.
I do not have the knowledge to say if the suggested digitalwritefast lib and using a digital dedicated port Like D10 and D11 could speed things up.

The C code looks much like C++ code or am I wrong?

With my knowledge I reworked that code (will not work and full of errors but it is that I understand what is going on to get the data retreived as fast as possible

Code: [Select]
#include <digitalWriteFast.h>

int ADDOPin = 10;
int ADSKPin = 11;
unsigned long Count;
unsigned char i;

void setup()
{
  Serial.begin(115200);
  pinModeFast(ADDOPin, INPUT);
  pinModeFast(ADSKPin, OUTPUT);
  Count = 0;
}

void loop()
{
  Serial.print(Count);
}

unsigned long ReadCount(void)
{
  while digitalReadFast (ADDOPin, LOW)
  {
    for (i=0;i<24;i++) // for channel A and 128X
      //for (i=0;i<26;i++) // for channel A and 64X
    {
      digitalWriteFast(ADSKPin, HIGH);
      Count=Count<<1;
      digitalWriteFast(ADSKPin, LOW);

      if digitalReadFast(ADDOPin) Count++;
    }
    digitalWriteFast(ADSKPin, HIGH);
    Count=Count^0x800000;
    digitalWriteFast(ADSKPin, LOW);
    return(Count);
  }
}




Paco

reworked the code


Never to old to learn and I learn every day

Robin2

Paco, As far as I can see the only speed limitation is the frequency of getting samples from the scale. I don't think that has anything to do with digitalWrite() being slow and using any other function won't speed it up.

If you are content with 10 (or 80) samples per second (sps) then all you need to do is decouple the reading of the scale from the individual steps of the motor.

For simplicity, let's work on 10sps.

You say you want the motor to cause 1mm of movement in one second, or, more usefully 0.1mm of movement between samples. How many steps must the motor make to acheive 0.1mm of movement?

When we know this, we can work out how to program things. It may be necessary/convenient/useful to make a small change to the library but let's leave that for the moment.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

backbone

Hi Robin,

Sorry I confused you with the steps.
I reframe.....
200 stepper steps is 360 degree = 2 mm pitch/compression
100 stepper steps is 180 degree = 1 mm pitch/compression
1mm over 1 second is 10 samples = 1 sample per 0,1 mm
I have no objection to step slower but then measuring takes a longer time.
Lets say the average compression is 35 mm that would take 35 seconds to go down.
If you measure 5 times in a row that would be  10 times 35 seconds as we also have to return the motor to its original position.
For this debugging I have no problem stay with this timeframe.
In a later stage I can always enhance.

Quote
then all you need to do is decouple the reading of the scale from the individual steps of the motor.

You mean controlling the stepper with its own controller?




Never to old to learn and I learn every day

Robin2


Quote
then all you need to do is decouple the reading of the scale from the individual steps of the motor.

You mean controlling the stepper with its own controller?


No. Based on the numbers you have supplied all I mean is that you get the stepper to move 10 steps at 0.01 second intervals between each reading of the scale. If I recall correctly, your earlier code only moved it one step between each reading.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

backbone

OK so the timingtable/storyboard should look like this:
1]
Start puls received from PC
Startflag = 1
Read in maximum value of compression ....35 mm from PC so counterMax is 35
Save current raw force value > rawValue.
Start rotation downwards in 18 degree steps = 0.1 mm
1 sample per 18 degree step = 0.1 mm
Measure raw force value each 18 degree step
rawValueOld = rawValue

2]
If rawValue > rawValueOld
counter = 0
Recordingflag = 1
send reset signal to pc so force value is set to zero
send reset signal to pc to start recording force and step value
Rotate motor in 180 degree steps
Serial.print(rawvalue)
Serial.print(counter)
Counter--
3]
if counter == counterMax (35)
Recordingflag = 0
Returnflag = 1
send reset signal to pc to stop recording force and step value
Rotate motor in 180 degree steps upwards
counter++
4]
if counter = - 4
Stop motor
Startflag = 0
Returnflag = 0


Paco
Never to old to learn and I learn every day

Robin2

Hi Paco,
I have to confess I can't follow your steps (perhaps because I am not as familiar with the experiment).

I'm not sure if this helps but the logic in my head is a bit like this

   for (number of scale readings) {
          read scale
          for (10 steps) {
                    step motor
                    wait 0.01 sec
          }
    }

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up