• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Sterowanie zdalne arduino
#1
Witam,
nie mam wielkiego doświadczenia w Arduino, ale pokleiłem sobie projekcik wyciągarki zdalnie sterowanej z automatycznie kontrolowaną siłą ciągu.
Wygląda to tak, że Arduino nr 1 ma podłączony potencjometr i wysyła przez nRF24 wartość procentową  jego położenia do Arduino nr 2. Odbiornik ma podłączony tensometr i serwo, które steruje przpeustnicą silnika spalinowego. Położenie serwa jest mapowane z przesłanej wartości procentowej. To działa dobrze i mogę sterować bezpośrednio serwem, kręcąc potencjometrem. Jednak problem jest z korekcją jeżeli ciąg ma być korygowany do siły zadanej na początku (setup). Napisałem prymitywną funkcję, która tym steruje (na dole załączonego programu "Serwom"), ale tak jakby jest ignorowana. Przekręcenie potencjometru zmienia położenie serwa, ale ręczne naciąganie potencjometru nie zmienia jego położenia, a niby powinno też zmieniać położenie serwa (żeby dążyć do zadanej siły). Co robię źle albo jak mogę to zrobić lepiej? Wiem, że będę musiał użyć PID, bo jest to układ nieliniowy, ale dlaczego ta funkcja akurat nie działa dobrze?
P.S. przepraszam za mieszankę polskich i angielskich opisów
Kod:
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
#include "HX711.h"


#define CE_PIN   9
#define CSN_PIN 10

//Waga
HX711 scale;
#define calibration_factor -21686 //This value is obtained using the SparkFun_HX711_Calibration sketch
#define DOUT  3
#define CLK  2
float waga = 0;

//Serwo
Servo Serwo;
int pozycja = 0;
int zmiana = 1;


LiquidCrystal_I2C lcd(0x27,20,2);  // set the LCD address to 0x27 for a 16
const byte thisSlaveAddress[5] = {'R','x','A','A','A'};

RF24 radio(CE_PIN, CSN_PIN);

int dataReceived; // this must match dataToSend in the TX
bool newData = false;

//===========

int Button = 4;
int confButton = 5;
unsigned long TimeNew;
unsigned long Time1=0;
unsigned long Time=0;
int force = 0;

void setup() {
  pinMode(Button, INPUT_PULLUP);
  pinMode(confButton, INPUT_PULLUP);

  Serwo.attach(8);
 
  scale.begin(3,2);
  scale.set_scale(calibration_factor); //This value is obtained by using the SparkFun_HX711_Calibration sketch

 
 
  lcd.init();                      // initialize the lcd
  lcd.backlight();
  lcd.setCursor(1,0);
  lcd.print("ustaw sile");
      while (digitalRead(confButton)==HIGH) //czekaj na przycisk
       {
         TimeNew=millis(); // licz odstepny między naciśnięciami
        if (digitalRead(Button)==LOW && TimeNew-Time>500)
        {
        Time=TimeNew;
        force = force +5;
          if (force >=95)
           {
          force =0;
           }
    }
   
  lcd.setCursor(1,1);
  lcd.print(force);
  delay(300);
  scale.tare();  //Assuming there is no weight on the scale at start up, reset the scale to 0
}

    Serial.begin(9600);

    Serial.println("SimpleRx Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1, thisSlaveAddress);
    radio.startListening();
   

  lcd.clear();
  lcd.setCursor(1,0);
  lcd.print("czekam na sygnal");
}

//=============

void loop() {
    getData();
    showData();
    Serwom();
}

//==============

void getData() {
    if ( radio.available() ) {
        radio.read( &dataReceived, sizeof(dataReceived) ); //odczytuje co przesłane
        newData = true;
       
    }
    waga = scale.get_units(4); //odczytuje siłę z tensometru;
}

void showData() {
    if (newData == true)
    {
        Serial.print("Data received ");
        Serial.println(dataReceived);
        lcd.clear();
        lcd.setCursor(1,0);
        lcd.print("zadana/aktualna");
        lcd.setCursor(0,1);
        lcd.print(dataReceived*force*0.01); //wyświetl przeliczone % na siłę
       
        lcd.setCursor(5,1);
        lcd.print(waga);
        newData = false;
    }
}
void Serwom()
{
  pozycja = map(dataReceived,0,99,0,180);
 
  if (force > waga && pozycja <170 && abs(force-waga)>1 ) //zmniejsz obroty jak siła za duża
  {
      pozycja = pozycja+10;
      Serial.println("malo");
  }

  if(force < waga && pozycja >10 && abs(force-waga)>1 ) // zwiększ oborty jak siła za mała
  {
      pozycja = pozycja-10;
     Serial.println("duzo");
  }
 
  Serwo.write(pozycja);
 
  }
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości