Sequential PWM Control of Electromagnetic Actuators

Hello

My programming skills are minimal and I am trying to piece together a sketch that will execute sequential PWM commands. I've hacked a lot of code but the target continues to elude me. The goal is to write a sketch that allows a user at the push of a button to direct the Arduino (Duemilanove) to:

PWM1 ramps from a starting position (1) to a higher value (x) and back to (1).

PWM2 Stops and holds.

PWM2 increments from a starting position (1) to a new position (y) and holds there.

Repeat the PWM1 cycle.

Repeat the PWM2 increment 9 more times with the PWM1 cycle executed once at each iteration of PWM2.

Then PWM1 and PWM2 return to their initial values (1,1) while…

PWM 3 increments to a new value (Z) and the whole PWM1 and PWM2 cycle repeats followed by the PWM3 increment until a 10 x 10 operation grid is complete)

If anyone is aware of sketches that carry out some or all of this type of operation please point me in the right direction – thanks!

I've hacked a lot of code

Well, show us the code you have so far. With [ code ] tags, please.

Ah, I guess I was premature - I don't have any code that works - that last sketch I tried to morph was a cross-fader similar to the one here - I need to educate myself further before pursuing this thread. Thanks.

You may find some ideas in Planning and Implementing a Program.

Look at {A} how the code is organized and {B} how millis() is used to manage timing.

…R

Hello - I'm back after a side trip to Raspberry pi land and then returning to Arduino land since it seems the PWM capabilities of the Arduino are better suited to the project on which I am working. Below is a sketch that seems to be working for at least two of the three axis I need to control with these electromagnetic actuators. I am not sure it is working correctly in the third axis. The goal is to 1. Move a full excursion in axis 1 (Z) 2. Increment a fix amount in axis 2 (X) 3. Increment a fixed amount in axis 3 (Y) when the excursion in X is at the max or min

It is the latter part that is most troublesome - I am using an LED to simulate the analogWrite function that should add the constant to the PWM signal to axis 3 and the LED flickers so I cannot be sure it is gaining signal at each cycle (which should be 5 loops through the program based on the fixed values I am using in this test). If anyone has a moment to look at this sketch and point out any logic or syntax errors I would appreciate it very much. Thanks.

/*MoveZ IncrementX */

int AxisZ = 0; // Z axis on controller ground state pin 11 int AxisX = 0; // X axis on controller ground state pin 10 int AxisY = 0; // Y axis on controller ground state pin 9 int zStep = 250; // excursion depth of Z axis int xStep = 50; // excursion of the X axis per Z cycle int yStep = 5; // excursion of the Y axis per complete X axis cycle

void setup() {

// declare pins 11, 10, to be outputs

pinMode(11, OUTPUT); pinMode(10, OUTPUT); pinMode(9, OUTPUT); }

void loop() { //One Z Axis excursion per loop

analogWrite(11, AxisZ + zStep); delay(500); analogWrite(11, AxisZ); delay(500);

// Move the X axis

analogWrite(10, AxisX);

// change the X excursion for next time through the loop

AxisX = AxisX + xStep;

//After each cycle move Y axis one yStep

if (AxisX == 0 || AxisX == 250) { analogWrite(9, AxisY + yStep); } // wait for 100 milliseconds for actuator settling

delay(100);

// reverse the direction of the xStep at maximum excursion of 250

if (AxisX == 0 || AxisX == 250) { xStep = -xStep ; } // wait for 100 milliseconds for actuator settling delay(100);

}

scalpshifter:
analogWrite(9, AxisY + yStep);

Don’t you need to treat AxisY the same way you have treated AxisX

And please modify your post and use the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum

…R

Thanks - I will insert code as you described henceforth - hope it is correct in this post.

The AxisY routine only advances once for every complete AxisX excursion (5 steps in X per line in this test). That is why I used the same syntax for the boolean "or" logic as with the AxisX reversing direction (i.e., when Xis 0 or 250, revers the direction - this should set up a rastering motion) except for AxisY I substituted the command to advance, rather than reverse sign, by a specific amount whenever the AxisX value reaches an end point (0 or 250). This is like a plotter putting 5 points on a line in one x direction, then incrementing one step to the next line, then returning in the x direction and placing 5 more points along the way. I have to figure out a way to say "stop loop when AxisY value reaches 250" but I have not gotten that far yet. thanks again for your comments -

 // Move the X axis

  analogWrite(10, AxisX);

  // change the X excursion for next time through the loop
  
  AxisX = AxisX + xStep;

  //After each cycle move Y axis one yStep
  
    if (AxisX == 0 || AxisX == 250) {
    analogWrite(9, AxisY + yStep);
  }
  // wait for 100 milliseconds for actuator settling
  
  delay(100);

  // reverse the direction of the xStep at maximum excursion of 250
  
  if (AxisX == 0 || AxisX == 250) {
    xStep = -xStep ;
  }

scalpshifter: The AxisY routine only advances once for every complete AxisX excursion (5 steps in X per line in this test). That is why I used the same syntax for the boolean "or" logic as with the AxisX reversing direction (i.e., when Xis 0 or 250, revers the direction - this should set up a rastering motion) except for AxisY I substituted the command to advance, rather than reverse sign,

I think you are confusing yourself (as well as me).

If you want the AxisY to advance why aren't you using AxisY = AxisY + Ystep

I wasn't commenting about the code that makes the decision when to advance the Y axis.

And there is no reason why you need to separate the lines

   if (AxisX == 0 || AxisX == 250) {
    analogWrite(9, AxisY + yStep);
  }
  // wait for 100 milliseconds for actuator settling

and

  if (AxisX == 0 || AxisX == 250) {
    xStep = -xStep ;
  }

Simplify it like this

   if (AxisX == 0 || AxisX == 250) {
    analogWrite(9, AxisY);
    xStep = -xStep ;
  }

...R

Thanks for the consolidation comment - as I learn the coding process I figured I would learn things like that to compact the code and avoid redundancies.

After a few days of raspberry pi trials and tribulations I have put that aside (I think I must have damaged the board because I cannot even make an LED blink by following their cut and past examples in Scratch…) and the arduino sketches are working great (micromovie here showing an EM actuator moving in steps of Z and X in a coordinated fashion - I have one out of the camera range moving in Y for every 5 steps of X).

Thanks again for your help - my next goal is to write a group of sketches that a user can download to the Arduino by just pressing a button in a GUI like Blynk - not sure how to do that but I am sure it is possible!

my next goal is to write a group of sketches that a user can download to the Arduino by just pressing a button in a GUI like Blynk - not sure how to do that but I am sure it is possible!

I am not sure that it is possible to do that. In fact I am quite sure you can't

scalpshifter:
Thanks again for your help - my next goal is to write a group of sketches that a user can download to the Arduino by just pressing a button in a GUI like Blynk - not sure how to do that but I am sure it is possible!

You could organize an Arduino program as a collection of functions and the user could choose which function is called.

It would help if you explain exactly what you want to achieve - describe the different sketches that you would like the users to be able to choose between.

…R

ha ha ha - that is great - I’m genetically predisposed to (try to) do things that can’t be done - so this is the perfect challenge- and thanks Robin2 for the suggestion.

Robin2:
It would help if you explain exactly what you want to achieve - describe the different sketches that you would like the users to be able to choose between.

Project Background: I started a company years ago that builds a molecular printer (badly) and sells it for over 100K - it’s a long (not so happy) story, but the bottom line is that I think this can be done for less than 3K and I will make the whole process open source because it is not about the money, it is about ethics : ) - so that is exactly what I want to achieve - a molecular printer (prints proteins, DNA, etc. onto biochips) made from inexpensive consumer parts and costs <3000 dollars to make.

The sketches will be different patterns based on X,Y,Z coordinate systems - ideally user-defined patterns as well as pre-programmed common arrays (e.g., 5 x 5 square array of 10µ diameter spots). Believe it or not this capability has utility in everything from stem cell research to materials development to electronic device prototyping. My focus is point of care molecular diagnostics and self-assembling DNA nanosystems - probably TMI, sorry!

Cinch by the inch…

Well most 3D printers and related machines use GCode with units of millimeters. Doing it with molecular units might not be too different. Have a look at how they work: maybe there’s some inspiration there.

scalpshifter: The sketches will be different patterns based on X,Y,Z coordinate systems

It seems to me you want your users to provide different data, not different sketches.

It would be perfectly practical to write an Arduino program that can do things based on data provided by a user - perhaps you could arrange for the user to operate a PC program that then sends the appropriate data to the Arduino. That is the way many CNC systems and 3D printers work.

...R

Thanks for the CNC and 3D printer info - I am delving into that now and learning about grbl, GCode and G-Code-Sender. I just hope I have enough years left in my life to understand, if not master, some of this stuff. I just spent the last few days wrestling with an ESP8266 board, python, esptool, firmware, and ended up back at the starting line (if that : ) - onward to GCode! thanks - Happy New Year.