Flysky and Motor

Heyy guys, I am using Flysky module to rotate a motor, I am using N20 encoder and LN298N motor Diver. The output I have set is RPM, No of turns, etc.

I want that when I turn the joystick up the motor should rotate and when I leave the joystick or pull it back to the initial position, the motor should rotate the same no of turns in the opposite direction as it has turned while moving the joystick up. This is my code, let me know what changes I should do.

#define ENCODEROUTPUT 1800

const int HALLSEN_A = 3; // Hall sensor A connected to pin 3 (external interrupt)

int in1 = 2;
int in2 = 11;
int enable1 = 5;  // pin with ~ symbol

int channel_2 = 6;  // pin with ~ symbol


//The sample code for driving one way motor encoder
volatile long encoderValue = 0;
long initialEncoderValue = 0;
int interval = 1000;
long previousMillis = 0;
long currentMillis = 0;

int rpm = 0;
boolean measureRpm = false;
int motorPwm = 0;

void setup() {

  pinMode(channel_2, INPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(enable1, OUTPUT);
  Serial.begin(57600);//Initialize the serial port
  EncoderInit();//Initialize the module


  encoderValue = 0;
  previousMillis = millis();
}

void loop() {
  int pwm = 0;
  int value = pulseIn(channel_2, HIGH, 25000);
  Serial.println(value);
  if (value == 0)
  {
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
    analogWrite(enable1, 0);
  }

  else if (value > 1530)
  {
    pwm = map(value, 1530, 2000, 0, 255);
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    analogWrite(enable1, pwm);
  }


  else
  {
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
    analogWrite(enable1, 0);
  }



  // Update RPM value on every second
  currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;


// Calculate the number of turns from the initial position
float turns = (float)(encoderValue - initialEncoderValue) / ENCODEROUTPUT;

// Only update display when there have readings
if (turns > 0) {
  Serial.print("Number of turns: ");
  Serial.print(turns);
}


    // Revolutions per minute (RPM) =
    // (total encoder pulse in 1s / motor encoder output) x 60s
    rpm = (float)(encoderValue * 60 / ENCODEROUTPUT);

    // Only update display when there have readings
    if ( rpm > 0)
    {

      Serial.print(encoderValue);
      Serial.print(" pulse / ");
      Serial.print(ENCODEROUTPUT);
      Serial.print(" pulse per rotation x 60 seconds = ");
      Serial.print(rpm);
       Serial.println(" RPM");
    }

    encoderValue = 0;

  }

}

void EncoderInit()
{
  // Attach interrupt at hall sensor A on each rising signal
  attachInterrupt(digitalPinToInterrupt(HALLSEN_A), updateEncoder, RISING);
}


void updateEncoder()
{
  // Add encoderValue by 1, each time it detects rising signal
  // from hall sensor A
  encoderValue++;
}

Be aware that not every helper have been playing with those things. Here is one.

Okey. Go on and make it come true. I see no problem.

How to do it is a problem :slight_smile:

Can you suggest how I can do it?

Show a complete circuit diagram and include specs on all devices used.

This is the circuit diagram.

Specification of devices

  1. A normal Arduino uno board.
  2. LN298N motor driver

IN1 & IN2 - Motor A input pins. Used to control the spinning direction of Motor A

IN3 & IN4 - Motor B input pins. Used to control the spinning direction of Motor B

ENA - Enables PWM signal for Motor A

ENB - Enables PWM signal for Motor B

OUT1 & OUT2 - Output pins of Motor A

OUT3 & OUT4 - Output pins of Motor B

12V - 12V input from DC power Source

5V - Supplies power for the switching logic circuitry inside L298N IC

GND - Ground pin

For more - L298N Motor Driver Module Pinout, Datasheet, Features & Specs

  1. Flysky module -
    FS-i6 Specifications:-
  • No. of Channels: 6 Channels

  • Model Type: Glider/Heli/Airplane

  • RF Range: 2.40-2.48GHz

  • Bandwidth: 500KHz

  • Band: 142

  • RF Power: Less Than 20dBm

  • 2.4ghz System: AFHDS 2A and AFHDS

  • Code Type: GFSK

  • Sensitivity: 1024

  • Low Voltage Warning: less than 4.2V

  • DSC Port: PS2;Output:PPM

  • Charger Port: No

  • ANT length: 26mm*2(dual antenna)

  • Weight:392 gm

  • Power: 6V (1.5AA x 4 Not Included)

  • Display mode: Transflective STN positive type, 12864 dot matrix VA7339mm, white backlight.

  • Size: 174 x 89 x 190 mm(LxWxH)

  • On-line update: yes

  • Color: Black

  • Certificate: CE0678,FCC

  • Model Memories: 20

  • Channel Order: Aileron-CH1, Elevator-CH2, Throttle-CH3, Rudder-CH4, Ch 5 & 6 open to assignment to other functions.

For more - Fly Sky FS-i6-Channel 2.4 Ghz Transmitter and FS-iA6 Receiver buy online at Low Price in India - ElectronicsComp.com

And as of now I have changed the code, this is te updated code -

#define ENCODEROUTPUT 1800

const int HALLSEN_A = 3; // Hall sensor A connected to pin 3 (external interrupt)

int in1 = 2;
int in2 = 11;
int enable1 = 5;  // pin with ~ symbol

int channel_2 = 6;  // pin with ~ symbol


//The sample code for driving one way motor encoder
volatile long encoderValue = 0;
volatile long totalTurns = 0;
long initialEncoderValue = 0;
int interval = 1000;
long previousMillis = 0;
long currentMillis = 0;
long previousTotalTurns = 0;
int rpm = 0;
boolean measureRpm = false;
boolean movingUp = false;
boolean movingDown = false;
int motorPwm = 0;
int Rotation = 0;
volatile long cur_enc = 0;
volatile long prev_enc = 0;

void setup() {

  pinMode(channel_2, INPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(enable1, OUTPUT);
  Serial.begin(57600);//Initialize the serial port
  EncoderInit();//Initialize the module
  encoderValue = 0;
  previousMillis = millis();
}

void loop() {
//  Serial.println(encoderValue);
  int pwm = 0;
  int value = pulseIn(channel_2, HIGH, 25000);
  
  if(value!=0){
    prev_enc = encoderValue;
    //Serial.println(value);
    if (value > 1450 && value < 1550)
    {
      //prev_enc = encoderValue;
      if(cur_enc < 0){
        forward();
        cur_enc = cur_enc + (encoderValue - prev_enc);
      }
      else if(cur_enc>0){
        backward();
        cur_enc = cur_enc - (encoderValue - prev_enc);
      }
      else{
        stop_r();
      }
      //Serial.print("    s   ");
      Serial.println(cur_enc);
      
    }
    else if (value > 1550 && value < 1750)
    {
      movingUp = true;      
      if (cur_enc < 10){
        forward();
        cur_enc = cur_enc + (encoderValue - prev_enc);
        Serial.println(cur_enc);
      }
      else{
        stop_r();
      }
        
      
    }
    else if (value > 1750 && value < 2000)
    {

      movingUp = true;      
      if (cur_enc < 20){
        forward();
        cur_enc = cur_enc + (encoderValue - prev_enc);
        Serial.println(cur_enc);
      }
      else{
        stop_r();
      }
    }
    else if (value > 1250 && value < 1450)
    {

      movingUp = false;      
      if (cur_enc > -10){
        backward();
        cur_enc = cur_enc - (encoderValue - prev_enc);
      //  Serial.print("    c   ");
        Serial.println(cur_enc);
      }
      else{
        stop_r();
      }
      
    }
    else if (value > 1000 && value < 1250)
    {
      movingUp = false;      
      if (cur_enc > -20){
        backward();
        cur_enc = cur_enc - (encoderValue - prev_enc);
       Serial.println(cur_enc);
      }
      else{
        stop_r();
      }
      
    }
    
  // Update RPM value every second
  currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
 
    rpm = (float)(encoderValue * 60 / ENCODEROUTPUT);
    float rotations = (totalTurns - previousTotalTurns) / (float)ENCODEROUTPUT;

    if ( rpm > 0)
    {

      previousTotalTurns = totalTurns;
    }

    //encoderValue = 0;

  }

}

void forward(){
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  analogWrite(enable1, 255);
}

void backward(){
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  analogWrite(enable1, 255);
}

void stop_r(){
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  analogWrite(enable1, 0);
}

void EncoderInit()
{
  // Attach interrupt at hall sensor A on each rising signal
  attachInterrupt(digitalPinToInterrupt(HALLSEN_A), updateEncoder, RISING);
}


void updateEncoder()
{

  encoderValue++; // Add encoderValue by 1, each time it detects the rising signal
  totalTurns++; // update total turns
}

By using this code the motor is rotating back, but it's rotating a little more no of turns back. I checked the reading of cur_enc it's taking longer time when it has to go back. Let me know if I miss something or if required any more details.

Hi,
Your schematic should have more connections than that, what about receiver gnd to UNO gnd, power supplies?

Can we please have a circuit diagram?
An image of a hand drawn schematic will be fine, include ALL power supplies, component names and pin labels.

Can you please post link to specs/data of the N20 motor.

Have you some simple code to check;
Your motor connections and control?
Your receiver connections and control?

What does or doesn't your code do?
Have you tried it?

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

Hey @TomGeorge , my bad that I missed that receiver. This is my connection.


part.

For Arduino Power supply I am using my usb connection with the computer.

These are the specifications of the motor -

|Model No.|GA12 N20|

|No Load Current (mA)|10 mA|
|No load Speed (RPM)|35|
|Rated Speed (RPM)|30|
|Rated Current (mA)|20|
|Rated Torque(kg-cm)|0.24|
|Stall Current (A)|1|
|Stall Torque(Kg-Cm)|2.0|
|Gear Ratio|298 : 1|
|Shaft Type|D-type
Single Side|
|Shaft Diameter (mm)|3|
|Weight (gm)|11|
|Screw Size|M3|
|Shipment Weight|0.016 kg|
|Shipment Dimensions|6 × 4 × 3 cm|

I have used the same code I made some changes in that and everything is working fine. I am getting the right encoder value. The rotation is good too. Overall it's working but the main objective that I have discussed above is still not working.

Basically, the objective is when the joystick is pulled up the servo should rotate n no of turns and when it is released, it should rotate the same no of n turns but in opposite directions.

Overall, it should store the change in the encoder value and then once released, use the same change in the encoder value to turn it back in opposite direction.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.