How can write no. 52 for direct manipulation port
No. 2 is 0b00000100;
No. 22 - ?
No. 23 - ?
No.52 - ?
No. 53 - ?
Hello Mikistromar,
I don't understand exactly what you mean/want but here a sample sketch that manipulates (blinks) a bit (pin 13 or L) of a port (B).
uint32_t pin_13 = (1u << 27); // mask for pin 13
void setup()
{
REG_PIOB_OER = pin_13; // pin 13 as output of port B
}
void loop()
{
REG_PIOB_SODR = pin_13; // turns pin 13 on (set)
delay(1000); // wait for a second
REG_PIOB_CODR = pin_13; // turns pin 13 off (clear)
delay(1000); // wait for a second
}
It is just about to find the port and mask of the pin that you want to manipulate. For example,
pin 2: mask= 25, port B.
pin 3: mask= 28, port C.
...
pin 36: Mask= 4, port C.
...
and so on. You can look for PORT PIN (pale yellow) of Graynomad's Arduino Due pinout diagram as a reference.
http://forum.arduino.cc/index.php?topic=132130.0
Good luck,
p
I have a program for Arduino Mini 16MHz, and I would use it for Arduino Due.
Mini has a digital port 2-13, but DUE has 22-53.
I need 22pin for encoder A and 23pin for encoder B for out 52pin - pulse and 53pin - step.
I do not know how i can write this code functioning for DUE.
#define encoder_a 2 //need for due 22pin
#define encoder_b 3 //need for due 23pin
#define motor_step 4 //need for due 52pin
#define motor_direction 5 //need for due 53pin
#include <delay.h>
volatile long motor_position, encoder;
byte inputA;
byte inputB;
void setup () {
//set up the various outputs
pinMode(motor_step, OUTPUT);
pinMode(motor_direction, OUTPUT);
// then the encoder inputs
pinMode(encoder_a, INPUT);
pinMode(encoder_b, INPUT);
// enable pullup as we are using an open collector encoder
digitalWrite(encoder_a, HIGH);
digitalWrite(encoder_b, HIGH);
// encoder pin on interrupt 0 (pin 2)
attachInterrupt(0, encoderPinChangeA, CHANGE);
// encoder pin on interrupt 1 (pin 3)
attachInterrupt(1, encoderPinChangeB, CHANGE);
encoder = 0; //reseet the encoder position to 0
}
void loop() {
//do stuff dependent on encoder position here
//such as move a stepper motor to match encoder position
//if you want to make it 1:1 ensure the encoder res matches the motor res by dividing/multiplying
if (encoder > 0) {
//digitalWrite(motor_direction, HIGH);// move stepper in reverse
PORTD = PORTD | 0b00100000;
//digitalWrite(motor_step, HIGH);
PORTD = PORTD | 0b00010000;
//digitalWrite(motor_step, LOW);
PORTD = PORTD & 0b11101111;
delayMicroseconds(600); //_delay_us(200); //modify to alter speed
motor_position++;
encoder = 0; //encoder--;
}
else if (encoder < 0) {
//digitalWrite (motor_direction, LOW); //move stepper forward
PORTD = PORTD & 0b11011111;
//digitalWrite (motor_step, HIGH);
PORTD = PORTD | 0b00010000;
//digitalWrite (motor_step, LOW);
PORTD = PORTD & 0b11101111;
delayMicroseconds(600); //_delay_us(200); //modify to alter speed
motor_position--;
encoder = 0; //encoder++;
}
}
void encoderPinChangeA() {
inputA = (PIND & 0b00000100) >>2; // result is 0b00000001 if input is high, 0b00000000 if input is low.
inputB = (PIND & 0b00001000) >>3; //result is 0b00000001 if input is high, 0b00000000 if input is low.
//if (digitalRead(encoder_a)==digitalRead(encoder_b)) {
if (inputA == inputB){
encoder--;
}
else{
encoder++;
}
}
void encoderPinChangeB() {
inputA = (PIND & 0b00000100) >>2; // result is 0b00000001 if input is high, 0b00000000 if input is low.
inputB = (PIND & 0b00001000) >>3; // result is 0b00000001 if input is high, 0b00000000 if input is low.
//if (digitalRead(encoder_a) != digitalRead(encoder_b)) {
if (inputA != inputB){
encoder--;
}
else {
encoder++;
}
}
Thanks for the example. How do yo determine the mask?
uint32_t pin_13 = (1u << 27); // mask for pin 13
Palliser:
You can look for PORT PIN (pale yellow) of Graynomad's Arduino Due pinout diagram as a reference.
Due pinout diagram - Arduino Due - Arduino Forum
Hello Palliser,
how can write this code: direct port digitalwrite high
PORTD = PORTD | 0b00000100; //digitalWrite(encoder_a, HIGH); this no.2 need number 22
PORTD = PORTD | 0b00001000; //digitalWrite(encoder_b, HIGH); this is no.3 need number 23
and this: digitalwrite high and low
//digitalWrite(motor_direction, HIGH);// move stepper in reverse
PORTD = PORTD | 0b00100000; // this no.5 need number 53
//digitalWrite(motor_step, HIGH); // this no.4 need number 52
PORTD = PORTD | 0b00010000;
//digitalWrite(motor_step, LOW);
PORTD = PORTD & 0b11101111; // this no.4 need number 52
I'm still a beginner and please write to me for more detail.
Or it will be better to rewrite this code. Is it possible to operate in only 8 bit system.
But i need code is worked to 32bit.
He told you already, look 4 post above!
There is no PORTA..E on the ARM. That is AVR-code!
As well check for attachInterrupt(), there you are also using the AVR parameters and not the DUE arm way to call it!
Try to make yourself familiar with the different hardware. Spent some time to view over the documentation of the controllers. Review some of the existing libraries, watch there especially the #ifdef-clauses, where things are coded for ARM or AVR.
Thanks for the answers, that is, I have to translate code from the ARM to AVR.
Since I do not know programming in AVR need help.
RE: masks
You can look for PORT PIN (pale yellow) of Graynomad's Arduino Due pinout diagram as a reference.
So ,
uint32_t pin_17 = (1u << 12); // mask for pin 17
uint32_t pin_20 = (1u << 12); // mask for pin 20
Then the masks are the same, but in use they are applied to different ports?
Yep. You can also look at the pin definitions in the variant.cpp file:
....\arduino-1.5.6-r2\hardware\arduino\sam\variants\arduino_due_x\
Lines 153 (pin 17) and 160 (pin 20). Also, to manipulate your pin, you should consider some definitions. For example:
-If pin will be used as pure output, use PIO_OUTPUT_O instead of PIO_DEFAULT.
-If pin will be used as pure input, use PIO_INPUT instead of PIO_DEFAULT.
-If pin needs internal pull-up, use PIO_PULLUP instead of PIO_DEFAULT, etc..
and depending of the nature of your application, you will need to choose the right peripheral (function). For example,
by default, pin A5 works as:
- Analog input if configured with peripheral X1 (extra function).
- Timer clock if configured with peripheral A.
- Input external wait signal with peripheral B.
CAVEAT: I use to catalog the info above as part of Due's 'deep waters', so be very careful if you decide to use it and mess with it.
p
Hi Palliser,
You can answer me can write code in 32 bit mode. Is it possible to translate described below code.
#define encoder_a 22
#define encoder_b 23
#define motor_step 53
#define motor_direction 52
volatile long motor_position, encoder;
void setup () {
pinMode(motor_step, OUTPUT);
pinMode(motor_direction, OUTPUT);
pinMode(encoder_a, INPUT);
pinMode(encoder_b, INPUT);
digitalWrite(encoder_a, HIGH);
digitalWrite(encoder_b, HIGH);
attachInterrupt(22, encoderPinChangeA, CHANGE);
attachInterrupt(23, encoderPinChangeB, CHANGE);
encoder = 0;
}
void loop() {
if (encoder > 0) {
digitalWrite(motor_direction, HIGH);
digitalWrite(motor_step, HIGH);
digitalWrite(motor_step, LOW);
delayMicroseconds(600);
motor_position++;
encoder = 0;
}
else if (encoder < 0) {
digitalWrite (motor_direction, LOW);
digitalWrite (motor_step, HIGH);
digitalWrite (motor_step, LOW);
delayMicroseconds(600);
motor_position--;
encoder = 0;
}
}
void encoderPinChangeA() {
if (digitalRead(encoder_a)==digitalRead(encoder_b)) {
encoder--;
}
else{
encoder++;
}
}
void encoderPinChangeB() {
if (digitalRead(encoder_a) != digitalRead(encoder_b)) {
encoder--;
}
else {
encoder++;
}
}
Hi Mikistromar,
So your code works fine with Arduino Mini but it doesn't work with Arduino Due. Hmm, as I use to say: Arduino Due is a different monster. Let's talk about the hardware:
Before you try to make the code run (even when it runs OK with your Mini), you should make sure you hardware, in this case, your I/O devices are the right ones for Due.
Question: -Are your stepper motor and encoder designed to operate at 3.3V?
Remember that Due operates at 3.3V and the Mini at 5V. If your answer is yes, so far so good but if you answer is no, you have two options:
- Replace them for 3.3 similar ones.
- Use voltage converter means between them and Due.
Some encoders are pure mechanical but others have chips that depend on the input voltage (3.3V, 5V). Similarly, some step motors operate at 3.3V or 5V. I recommend you to use only 3.3V I/O devices, basically, to protect Due.
Let's talk about software.
Your code is relatively simple but it is not quite clear to me what you want to do with it. It looks like you want to control the step motor with the encoder using interruptions. Am I right? If so, why to migrate from Mini to Due? better time response I guess?
Regarding interrupts, one good news about Due is that you can attach an interrupt function on all its pins.
Continuing with your code, only for debugging purposes, you should use the serial function to determine if your code is running or not.
Anyway, I'd recommend you to start testing your I/O devices and Due using simple example sketches separately. For example, try the example 1 of the Arduino playground (rotary encoder) and see if the encoder counts OK or not. Then you can move to another example with interrupts, etc...and please, keep us posted about your progress. regards!
p
Hello Palliser,
I have a problem on Arduino Mini to, because I replaced with faster DUE. On both the same error whit the same code. If the encoder quickly turn signals are lost in the step signal. I surveyed with an oscilloscope. Even when I used the code for direct manipulation port (MINI) there was no improvement.
To the Arduino due I used encoder with 3.3V signal, because it can destroy due if use 5V signal.
I tried all the possibilities but only one I have left to recompile the code in 32bit operation.
Work 8bit is slow, so the only option that works in 32bit.
The program only works if you slowly turn the encoder. If you are on the encoder fast scrolling code crease signal.
View: Arduino Encoder to Stepper Motor - YouTube