Timer and Firefly


#1

I wrote a quick script that utilizes the standard Firefly Firmata with an Arduino Uno to drive a stepper motor via manually pulsing. I have a small python script that puts out 1s and 0s (alternating) with each refresh of the timer. Through my testing, I am finding that there is a disconnect between the timer interval and the time it takes to execute the script. When I pulse 200 times for 1 ms each, it takes around ~10 seconds, but I am expecting it to only take .2 seconds. Is timer maybe not the correct tool for this application? Is there a better timing tool?

I know there is a piece of Firefly code that drives steppers specifically, and I have successfully gotten it to work.


#2

Maybe it is too much to expect timing in grasshopper to be lag-free enough to drive a motor smoothly. But I am still interested in a work around for the timer component. In the past I have written python scripts that simulate/animate a model by using the timer component to step through time/frames. I have tried time.sleep() in python, but the component never outputs until it is completely done calculating. I tried printing to get live feedback from “out”, but that does not display til the component is completely done calculating either.

Can time be controlled by any other way than the timer component?


#3

I gave the Quad Stepper Motor Stream component another look and I am finding that it does not function as I would expect. The motors have a set speed and acceleration, which means that if two motors are given two different angles to travel, one will finish before the other. Lets say I had a CNC router and I wanted to drive it through Firefly/Arduino. If I were to cut along a 30° path, the Y axis would reach its destination before X axis since there is more X distance to travel. Even if I had one Arduino for the X axis and one for the Y axis, I would run into problems with the acceleration (which happens on its own, and I am not sure how to control it).

This is more reason why I wanted to drive the steppers manually.


#4

Hi
I am stuck in the exact same step since a week right now… please tell me you found a solution… I even thought it could be the motor so I drove it with the arduino IDE and it worked fine… it seems like the firefly firmata is designed somehow to change the signal every 60 ms or so …

Did you find a way around?
Thanks


#5

I also tried the firefly timer counter component… the result is typical


#6

In the end, coordinating my two motors with perfect timing was not critical. Motor 1 runs, then motor 2 runs (using the quad stepper motor component).The way I managed to control the sequence was by using a timer on my python script to force it to refresh, while also using sticky variables so python could remember how far along it was in the sequence. I also used time.sleep() to get grasshopper to stop long enough for the motor to execute its motion.

This is what happens:

  1. python calculates and outputs new motor 1 position
  2. timer refresh
  3. python sleeps for a time proportional to motor 1’s motion
  4. timer refresh
  5. python calculates and outputs new motor 2 position
  6. timer refresh
  7. python sleeps for a time proportional to motor 2’s motion

Note that both motors positions are output each time. If the position does not change, the motor does not move. Therefore to move motor 1, output a new position for motor 1 and the current/old position for motor 2.


#7

Thanks… the problem is that the pulses are not sent fast enough… I didn’t implement anything to the actual application, not there yet… it’s just that it is working but the pulses are not sent in a good sequence time wise… I tried it with the arduino IDE and it worked, but it’s pretty important for my work flow to do it with grasshopper… any way around that???..
P.S. that’s on one motor only


#8

I ended up using the quad stepper motor component. I found that that pulsing produced poor quality of motion and was difficult to time properly. Like I said in previous posts, the grasshopper timer refresh does not really refresh at the stated interval because of the time it takes to calculate through the components. Plus, fast computers will calculate faster, while slow computers will calculate slower, causing the frequency of the pulses to vary from computer to computer.


#9

The quad step motor is not working with me… I am using 28byj motor with a uln2003… just can’t figure out how to control it… that’s why I’m sending the signals directly…
Any trick here?

Thanks


#10

I do not know how you have it set up. My questions/comments would be:

  • Did you load the stepper motor program via arduino IDE?
  • Does you motor have 4 wires?
  • Are the wires paired correctly?
  • The quad stepper component takes position data. So if your motor is set to 200 steps, you can go half circle with 100 and two more circles with 500 (100+200*2).

#11

thanks for your help,

right now I ended with creating a grasshopper definition that calculates the PWM for the motions of the motors, to perform some 2d mill moves…

The motions are time syncronized by microstepping so that the motors will perform the desired movements…

The problem is that for such approach there is a huge number of pulses, as the example in the photo.

I am looking for a way to send these pulses to the arduino pins in some time interval (as the motor would accept).

any suggestions???

Thanks again


#12

How very timely that you ask this question now. I no longer use firefly at all. It did not work well for me and did not provide the control and functionality I needed. I recently adjusted my workflow so that grasshopper only outputs motor commands, and then a Python script (outside of Rhino/Grasshopper) sends the commands over to the Arduino. To elaborate:

  1. Grasshopper outputs a text file with motor positions
  2. A standalone python script then reads the text file and sends the commands to Arduino via PySerial.
  3. The Arduino script does a series of Serial.read() to gather the next position for each motor.
  4. The Arduino script then uses the AccelStepper library to drive the stepper motors.
  5. Repeat steps 2-4

To communicate with Arduino, the consensus seems to be that PySerial is the easiest (I don’t think PySerial works within GhPython, so I ended up writing a standalone python script). But even then, there was a bit of a learning curve since managing serial communication is not something I had experience with. Writing from Python is easy, reading from Arduino is tough (read this to get up to speed http://forum.arduino.cc/index.php?topic=396450). I know Python, but I did not know C++ (Arduino’s language), so getting serial communication to work required a lot of trial and error. AccelStepper is pretty easy to use, but if you are sending PWM, it sounds like you are using servos. I am pretty sure you can write PWM directly from Arduino’s analog pins, but I don’t know if you will be able to control the acceleration or timing of the motors (like having two motors reach their destinations at the same time) without using a library.

A lot of people use Arduino, so most of the questions that will arise may have already been asked and answered. Do a google search and you can probably find a lot of answers.

I built a robotic arm a few years ago that took PWM. I had to micromanage each joint since the script that controlled the servos did not do any sort of calculation (with regard to smoothing out the motion). My text files were 10,000-100,000 lines long.


#13

Hey,

what you did is almost exactly my plan except I am using grasshopper a bit more (for some reasons later on when the machine gets to work)… Grasshopper translates the moves and calculates the pulses in PWM, saves all to a text file, saves the file to an SD card, the arduino reads the pulses line by line from the SD card and sends the values line after line.

I am planing on using Steppers not Servos… The PWM is for the microstepping, which is my method of synchronizing the moves (for ex. one motor will work full stepping for 4 steps and the other half stepping for also 4 steps, to get the slope of 25%). This way the motors will reach the desired position the same time. The libraries are great for one motor, but I could not manage to write something to synchronize 3 motors, and the internet was of no help…

Reading about similar problems, the SD card shield seems like the answer, but I still did not manage to make it work.Still suffering with it and the arduino shield

It is just a simple program that I need, it reads the values in the form of for ex.:
200,100,0,0,255,0,0,255,0,0,0,0
150,200,0,0,255,255,0,0,0,0,0,0

but a lot.

Then sends these values to the arduino pins with an analog write.

And yes you are right… Firefly in this case is not the most helpful.

The search is on going


#14

How are you driving the steppers with PWM? I am only aware of two scenarios:

  1. Connect the wires of the stepper directly to the pins of the Arduino. Send HIGH and LOW to the pins in a coordinated fashion to get the motor to turn. This does not work well because motion is not smooth, you have to control speed with your own algorithm, and you have to manage timing with the other functions in your script. Plus, the Arduino does not put out enough voltage to drive medium/large steppers this way.
  2. Connect the wires of the stepper to a stepper driver. This is highly recommended. In this case you send direction (as HIGH or LOW) to the stepper driver. And you alternate HIGH and LOW to step (microstepping is determined by switches on stepper driver). You can use the AccelStepper library to coordinate two stepper motors. This library will also take care of speed and acceleration.

#15

The first is not electrically recommended as you mentioned.

The second is doable by PWM… Instead of sending High LOW signals, you send PWM 0-255

By alternating the PWM values the same way as in wave drive, you get the microstepping values you need. The cool thing about microstepping calculation is that it is a function (sin and cos) according to the desired microstepping angle (it is better explained online, but in short, a pin is full, and it decreases while the next pin increases from 0).

I tried it, it works… Of course one cannot imaging any microstepping value is doable, but it is calcultabale, and then what the motors achieve, with a good motor probably max is 1/32 angle. but it doesnot matter if you need a microstepping value of 1/50 because the motors will do the best they can and since it is very small, in the application this will not be very visible.

The rest is totally right, controlling speed is not cool or easy, the same for acceleration and all the benefits of as fix microstepping using the driver ot the libraries. But since it is an XY table, synchronization is very critical than anything else.