Go Down

Topic: Port Registers instead of just pin number (Stepper motors) (Read 5677 times) previous topic - next topic

DonnyM

Oct 15, 2013, 10:13 pm Last Edit: Oct 16, 2013, 12:14 am by DonnyM Reason: 1
I have a 5 motor rig that i would like to use Dragon Frame with. I have a Megatronics controller that has stepper driver sockets built into it and its based on a Mega 2560.
The DragonFrame DFMoco Sketch uses Port Registers instead of pin numbers for the step and direction pins. Also the pin numbers called to by the DFMoco are different than the Megatronics board I am trying to use.
I need to figure out how to set the Megatronic Pin numbers in the DFMoco Sketch.
Code: [Select]
This is from a sketch that works with the Megatronics.
#define X_STEP_PIN 26
#define X_DIR_PIN 27
#define X_ENABLE_PIN 25
#define X_MIN_PIN 37
#define X_MAX_PIN 40

#define Y_STEP_PIN 4 // A6
#define Y_DIR_PIN 54 // A0
#define Y_ENABLE_PIN 5
#define Y_MIN_PIN 41
#define Y_MAX_PIN 38 //15

#define Z_STEP_PIN 56 // A2
#define Z_DIR_PIN 60 // A6
#define Z_ENABLE_PIN 55 // A1
#define Z_MIN_PIN 18
#define Z_MAX_PIN 19

#define E0_STEP_PIN 35
#define E0_DIR_PIN 36
#define E0_ENABLE_PIN 34

#define E1_STEP_PIN 29
#define E1_DIR_PIN 39
#define E1_ENABLE_PIN 28

#define E2_STEP_PIN 23
#define E2_DIR_PIN 24
#define E2_ENABLE_PIN 22


And this is the DFMoco sketch:
Code: [Select]
#define MOTOR0_STEP_PORT PORTG
#define MOTOR0_STEP_PIN B00100000

#define MOTOR1_STEP_PORT PORTH
#define MOTOR1_STEP_PIN B00001000

#define MOTOR2_STEP_PORT PORTH
#define MOTOR2_STEP_PIN B00100000

#define MOTOR3_STEP_PORT PORTB
#define MOTOR3_STEP_PIN B00010000

#if ( PINOUT_VERSION == 2 )

#define MOTOR4_STEP_PORT PORTA
#define MOTOR4_STEP_PIN B01000000

#define MOTOR5_STEP_PORT PORTC
#define MOTOR5_STEP_PIN B10000000

#define MOTOR6_STEP_PORT PORTC
#define MOTOR6_STEP_PIN B00100000

#define MOTOR7_STEP_PORT PORTC
#define MOTOR7_STEP_PIN B00001000

#elif ( PINOUT_VERSION == 1 )

#define MOTOR4_STEP_PORT PORTA
#define MOTOR4_STEP_PIN B00000001

#define MOTOR5_STEP_PORT PORTA
#define MOTOR5_STEP_PIN B00000100

#define MOTOR6_STEP_PORT PORTA
#define MOTOR6_STEP_PIN B00010000

#define MOTOR7_STEP_PORT PORTA
#define MOTOR7_STEP_PIN B01000000

#endif

#else

#define MOTOR0_STEP_PORT PORTD
#define MOTOR0_STEP_PIN B00010000

#define MOTOR1_STEP_PORT PORTD
#define MOTOR1_STEP_PIN B01000000

#define MOTOR2_STEP_PORT PORTB
#define MOTOR2_STEP_PIN B00000001

#define MOTOR3_STEP_PORT PORTB
#define MOTOR3_STEP_PIN B00000100

#endif




It looks like the Dragon Frame Sketch uses Port Registers instead of just specifying a port number. This method if faster and takes less code but more problematic if you want to change pins.

So for what I can gather so far it works like this
DragonFrame default sketch. This is Digital Pin 4
Code: [Select]
#define MOTOR0_STEP_PORT PORTG //PG5 ( OC0B )
#define MOTOR0_STEP_PIN B00100000 //sets 5 to high pin 4


My board uses pin 26 for the step on Motor0. which would be:
Code: [Select]
#define MOTOR0_STEP_PORT PORTA //PA4 ( AD4 )
#define MOTOR0_STEP_PIN B00010000 // sets 4 to high pin 26

Easy enough I think for the Step. Now for the direction:
Code: [Select]
// initialize motor structures
for (int i = 0; i < MOTOR_COUNT; i++)
{
// setup motor pins - you can customize/modify these after loop
// default sets step/dir pairs together, with first four motors at 4/5, 6/7, 8/9, 10/11
// then, for the Mega boards, it jumps to 28/29, 30/31, 32/33, 34/35
#if ( PINOUT_VERSION == 2 )
motors[i].stepPin = (i * 2) + ( (i < 4) ? 4 : 20 );
#elif ( PINOUT_VERSION == 1 )
motors[i].stepPin = (i * 2) + ( (i < 4) ? 4 : 14 );
#endif

motors[i].dirPin = motors[i].stepPin + 1;

Little confused here.
My Motor0 Dir pin is 27 so this should work I think. But for other motors I am not sure how to make this work for me. My motor 1 is Pin 4 for Step and 54 for for direction. StepPin+1 does not work for this.
Also I am not sure if I am missing something else. I get a clicking and no motor movement. If I load my own sketch for this shield all the motors run fine. So its just how I have it configured in the DFMoco sketch
Because my motor 0 should work if I set to PortA and Set 4 to high which is Pin 26. I am sure I am missing something about the dir pin setup or maybe need a enable. Not sure.
I tried posting this on the Dragon Frame board a couple weeks ago and received no suggestions. Since this is a Arduino board and code I thought I would try here.
I can make the DFMoco move my motors by just hooking up a 2560 and external steppers but I want the compact size of using the all in one Megatronics board since I have a extra laying around and for portability

Help,
Donny

.

nickgammon

Why is half your post in italics? Please use code tags where applicable.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

DonnyM

Sorry about the lack of code blocks. :smiley-red: I copied and pasted several pieces of several messages I posted on other forums that I received no help from. I have sens edited it to conform more to this forums standards. Not sure why some was in Italics.

Donny


Robin2

#3
Oct 16, 2013, 09:33 am Last Edit: Oct 16, 2013, 12:46 pm by Robin2 Reason: 1
(NB this has been corrected following @Grumpy_Mike's comment)

If you look at the pin-out diagram it should be obvious which physical pin is associated with which bit in the different port registers.

You can turn a bit in a port register to 1 with this (using bit 1 of portB as an example) - it doesn't affect the state of any of the other bits.

Code: [Select]
PORTB = PORTB | B00000010 ("|" is the symbol for "OR")

And you can turn a bit to 0 with this (without affecting other bits)

Code: [Select]
PORTB = PORTB & B11111101

Remember that some Ports use some of the bits for system purposes so you shouldn't disturb them.

You can similarly set bits in the data direction registers using DDRB (B, for example). This is the equivalent of pinMode(). A bit set to 1 signifies an output.

...R

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

Robin2

Thanks for spotting that @Grumpy_Mike. I had a feeling it was going to be wrong!

I have corrected the orginal.

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

Grumpy_Mike


DonnyM

I think I have the Port and bit set right to define the step pin number in the first part of the code.
The last part of the code below sets the step and direction pins to Outputs. Which should be right since it looks like a variable.
I am using Pinout Version 2. Not sure how to customize the pins after the loop. Not a programmer.

Code: [Select]
  // setup motor pins - [color=red]you can customize/modify these after loop[/color]
    // default sets step/dir pairs together, with first four motors at 4/5, 6/7, 8/9, 10/11
    // then, for the Mega boards, it jumps to 28/29, 30/31, 32/33, 34/35
    #if ( PINOUT_VERSION == 2 )
      motors[i].stepPin = (i * 2) + ( (i < 4) ? 4 : 20 );
    #elif ( PINOUT_VERSION == 1 )
      motors[i].stepPin = (i * 2) + ( (i < 4) ? 4 : 14 );
    #endif
   
    motors[i].dirPin = motors[i].stepPin + 1;
    motors[i].dir = true; // forward
    motors[i].position = 0L;
    motors[i].destination = 0L;

    motors[i].nextMotorMoveSteps = 0;
    motors[i].nextMotorMoveSpeed = 0;
   
    setPulsesPerSecond(i, 5000);
  }


  // set output pins
  for (int i = 0; i < MOTOR_COUNT; i++)
  {
    pinMode(motors[i].stepPin, OUTPUT);
    pinMode(motors[i].dirPin, OUTPUT);
   


My pin numbers need to be 26/27, 4/54, 56/60, 35/36, 29/39, 23/24 (only doing 6 step and dir of the 8)
My step pins don't follow the convention in this part of the code:
Code: [Select]
motors[i].stepPin = (i * 2) + ( (i < 4) ? 4 : 20 );

My direction pins don't not follow the convention of:
Code: [Select]
motors[i].dirPin = motors[i].stepPin + 1;

There is not DDR Data Direction Registers in the code. Since it defines PinMode for Outputs I don't think I would need that.
Code: [Select]
// set output pins
  for (int i = 0; i < MOTOR_COUNT; i++)
  {
    pinMode(motors[i].stepPin, OUTPUT);
    pinMode(motors[i].dirPin, OUTPUT);
   

Quote
Remember that some Ports use some of the bits for system purposes so you shouldn't disturb them.

How do I know what those bits are?

The last part that has me confused is that it disables PMW See Below
Code: [Select]
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)

    // disable PWM
    switch (motors[i].stepPin)
    {
      #if defined(TCCR3A) && defined(COM3B1)
      case 4:
        TCCR3A &= ~COM3B1;
        break;
      #endif

      #if defined(TCCR4A) && defined(COM4A1)
      case 6:
        TCCR4A &= ~COM4A1;
        break;
      #endif

      #if defined(TCCR4A) && defined(COM4C1)
      case 8:
        TCCR4A &= ~COM4C1;
        break;
      #endif

      #if defined(TCCR2A) && defined(COM2A1)
      case 10:
        TCCR2A &= ~COM2A1;
        break;
      #endif
    }
   
#else
   
    switch (motors[i].stepPin)
    {
      #if defined(TCCR1A) && defined(COM1B1)
      case 10:
        TCCR1A &= ~COM1B1;
        break;
      #endif

    }

#endif
  }

Yes some of my new pin numbers are PMW some are Analog Not sure how to apply the above to my new pins. Not sure if I need to turn the Analog to Digital. Again my new pins are 26/27, 4/54, 56/60, 35/36, 29/39, 23/24.

To sum it up it looks like I am defining the Step pins in two locations and the direction pins are the math formula based on the step pin number.

Thanks in advance for any suggestions.

Donny


(NB this has been corrected following @Grumpy_Mike's comment)

If you look at the pin-out diagram it should be obvious which physical pin is associated with which bit in the different port registers.

You can turn a bit in a port register to 1 with this (using bit 1 of portB as an example) - it doesn't affect the state of any of the other bits.

Code: [Select]
PORTB = PORTB | B00000010 ("|" is the symbol for "OR")

And you can turn a bit to 0 with this (without affecting other bits)

Code: [Select]
PORTB = PORTB & B11111101

Remember that some Ports use some of the bits for system purposes so you shouldn't disturb them.

You can similarly set bits in the data direction registers using DDRB (B, for example). This is the equivalent of pinMode(). A bit set to 1 signifies an output.

...R



Robin2

I don't have much time to deal with this now.

My reference to not disturbing pins was only meant to suggest that you use code which only affects the pins you want to use and doesn't affect other pins.

I think it would help you (and certainly me) if you draw up a table with columns that relate the different pins that you need to use, their port references and (if appropriate) the differences between the devices you are trying to match. (That's how I relate things when I am trying to transfer code from one device to another).

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

DonnyM

Attached is a preliminary image of the spreadsheet.
The ones under the dragon frame are the ones in the sketch. The ones under the megatronics are the pins I need to use in the sketch.

Donny

Robin2

That's the sort of thing I had in mind, and it's nice and neat.

I think it would be clearer if you had each pin on a different line.

It looks like pin4 is in PortG in one device and PortA in the other. Is that correct? (Just as an example).

It would also be helpful to have each line represent a common function, maybe it does but it's not clear why motor 0 and Axis x are on the same line but appear to be in different devices (for example).

Keep going and it will all become clear...

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

DonnyM

I uploaded another image. The first one had a wrong port number on it.
Each motor has a step and direction pin assigned to them.
Lets take motor 0 it is pin 4 and 5. I need to use pins 26 and 27 with the new board.
Direction pins are listed on the dragon frame side and the Megatronics side.
I am stumped at Motor 2 since its Pin 56 and 60. I don't see those on the Pin Mapping for the 2560. But its in the working script for that board for that motor. Unless they use the actual pin number and not the digital pin number. I don't know. (i.e step pin 4 dragonframe script is actually Pin 1  PG5 (Oc0B) on the pin mapping page.
How do I find out if the pins on the Megatronics are like the ones in the dragonframe script?
Still stumped on dir pins also. But one step at a time.

Donny


Robin2

As I said earlier you would be better to give each pin a different line so that each motor has two lines, one for step and one for direction.

If you are trying to match pins from two different products it might also be useful to make two separate tables to start with - that way you would not be trying to force inconvenient cross-matches. It would also allow you to verify correspondence with Arduino notation without getting confused about whether X in device 1 is the same as Y in device 2.

Collect and understand the data first, and then move on to cross-matching.

At some point you need a table that has each function (eg motor0 step) on a separate line with the pins for each board noted on the same line.

In the stuff you posted earlier there is a reference that pin 60 is also analog pin 6
Quote
#define Z_DIR_PIN 60 // A6
. The analog pins can also be used for digital I/O. However the pin cross reference on the Arduino product pages http://arduino.cc/en/Main/ArduinoBoardMega2560 doesn't show pin number 60, so I don't know if that is standard Arduino notation. A bit of Googling may help.

I have no idea what DragonFrame, DFMoco or Megatronics are. It looks to me that Megatronics is the hardware and DragonFrame is some different software you want to get working with the Megatronics hardware, but I may be wrong and I'm not sure where DFMoco fits in. If I'm right you will need to ensure that the DragonFrame software uses the pins in the way the Megatronics hardware expects. And if you alter the pin usage within the DragonFrame sketch you will also need to ensure that the changes don't screw up something else in the sketch.

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

DonnyM

Outline:

Definitions:
DFMoco; Arduino Sketch that works on Arduino 2560 hardware
DragonFrame;  Software that controls a Arduino board running the DFMoco Sketch
Megatronics;  Hardware that has a Ardunio 2560 chip in it but has a breakout board for stepper motors that uses different pins

Goal:
To use the Megatronics (Hardware) running a Modified Sketch (DFMoco) to be controlled by the DragonFrame Software

Solution:
Convert the pins that are used in the Megatronics (hardware) to work in the DFMoco (sketch)
The DFMoco Sketch uses Port Registers for Step pins. Also has a formula to specify the direction pins based on there relation to the step pins. This needs to be changed. See below.
Or since the DFMoco sketch already has previsions for 4 different style boards including a Arduino 2560. Maybe just add the Megatronics to it. Just like one does into a Marlin Sketch to control a printer. The Marlin Sketch has almost a dozen different pin configuration for all the different boards that can be run with it. And of course I don't know how to do this.

Outcome:
If the Pins of the Megatronics (hardware) are properly specified in the DFMoco (sketch) none of the rest of the sketch will need to change and the DragonFrame Software will be able to control the Megatronics (hardware).

OK cleaned up the spreadsheet a little better per your suggestions. See attached Image.
It now has better heading to make it easier to understand.
I have also filled in the new Ports and Pins for the Megatronics (hardware)  converted to the DFMoco Sketch style.
Now I only have one pin in question for the step pins on the Megatronics board. I am waiting to here back from the creator of the board to verify the correct Pin Number whether it is Digital Pin 4 or Analog Pin 6. This is for Motor 1 Y step.
If it is DP4 then I now know all the correct conversions for the Step Pins in the first part of the code.
There is a line that defines the step pins again so that they can be used in a formula to define the Direction pins. (As far as I can tell)
Code: [Select]
// initialize motor structures
  for (int i = 0; i < MOTOR_COUNT; i++)
  {
    // setup motor pins - you can customize/modify these after loop
    // default sets step/dir pairs together, with first four motors at 4/5, 6/7, 8/9, 10/11
    // then, for the Mega boards, it jumps to 28/29, 30/31, 32/33, 34/35
    #if ( PINOUT_VERSION == 2 )
      motors[i].stepPin = (i * 2) + ( (i < 4) ? 4 : 20 );
    #elif ( PINOUT_VERSION == 1 )
      motors[i].stepPin = (i * 2) + ( (i < 4) ? 4 : 14 );
    #endif
   
    motors[i].dirPin = motors[i].stepPin + 1;


I am converting Pinout Version2
Code: [Select]
motors[i].stepPin = (i * 2) + ( (i < 4) ? 4 : 20 );
How do I define this so its for Step pins 26,4,A2,35,29,23

On to direction Pins. This confuses me. In the DFMoco  sketch
Code: [Select]
motors[i].dirPin = motors[i].stepPin + 1
My direction pins are not the step pin +1 for all motors. Only 3 of the 6 use this convention
Direction Pins are 27,A0,A6,36,39,24

I need a new way to specify the direction pins.
Maybe if If there was a formula to list each motors Step pin with proper number instead of:
Code: [Select]
motors[i].stepPin = (i * 2) + ( (i < 4) ? 4 : 20 );
Then there would need to be a formula to specify the Dir pin other than
Code: [Select]
motors[i].dirPin = motors[i].stepPin + 1

Also attached is the original DFMoco Sketch. It has not been edited with the new Pins.
Maybe a better way would be just to add the Megatronics as a new board. But that may not work since it auto senses what board it is and the Megatronics board comes up as a Arduino 2560. Even still The Variable would still need to be defined by a formula.

thanks,
Donny



Robin2

What does PINOUT_VERSION signify?  If that is what distinguishes one board from another then there is nothing to stop you creating a new section a bit like this

Code: [Select]

if (PINOUT_VERSION == 3) {
motors[0].stepPin = whatever number you want
motors[0].dirPin  = whatever
motors[1].stepPin = whatever
motors[1].dirPin = whatever
etc
etc
}


This would HAVE to go in after all the existing code that sets direction pins - probably after the line
Code: [Select]
motors[i].dirPin = motors[i].stepPin + 1;

This is not an elegant solution but it should work for you.

I don't know if A2 can be used in this format or if you will need to find out the equivalent digital pin number. (Suck it and see if it compiles)

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

Go Up