Сервопривод

dreamol
Offline
Зарегистрирован: 19.07.2016

Добрый день, подскажите пожалуйста как решить проблему:

Имеется UNO к ней подключен дисплей Nextion, датчик DS18B20, компьтерный вентилятор и сервопривод FS90.

Так вот проблема: Сервопривод дрожит градусов на 5-10 при посылки данных на Nextion через UART, то есть у меня данные на дисплее обновляются кажные N секунд, так вот и сервопривод через каждые N секунд колеблется, после полебаний встает на заданный угол.

Что пробовал: Питание сервопривода подключал и напрямую и через отдельный блок питания, землю обьединял, пробовал через конденсаторы.

На другой пин тоже пробовал.

Вариант делать detach() перед обновлением экрана не подходит. 

Если у кого была такая проблема, посоветуйте решение.  

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Прежде, чем найти решение, следует понять, в чем состоит проблема.

Дело в том, что управление сервой требует точно выдерживать длительность импульса. Подозреваю, что и для обмена с дисплеем точность временнЫх интервалов также должна выдерживатья достаточно строго.

Значит, что-то чему-то мешает.

Кстатит, как подключаете UART, если в Uno он уже занят USB?

И самое интересное, а почему Вы решили, что "делать detach() перед обновлением экрана не подходит"?

dreamol
Offline
Зарегистрирован: 19.07.2016

про UART не правильно указал, nextion подключен через 2 и 3 пин, серва на 6 пине.

detach() не подходит, потому что, на экране есть кнопки управления углом сервы, если в этот момент нажать кнопку серва не реагирует.

 

 

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Правильно ли я понимаю, что используется SoftwareSerial?

Неочевидно, что он дружит с Servo.

Так что, вероятно, какую-то из библиотек придется переписывать.

Или заменить Uno на Mini с подключением Nextion через аппаратный Serial.

Или все-таки делать detach. Вряд ли обмен с дисплеем жрет заметный процент времени.

 

PS. Да, я не понял, почему "серва не реагирует"? Вы ведь опрашиваете состояние сенсорного экрана? Значит, можете обеспечить, чтобы сигнал на перемещение сервы проходил только тогода, когда серва подключена.

Собственно, подозрение, что проблема не в библиотеках (хотя могла бы быть), а во внутренней логике Вашей программы.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Код бы ещё глянуть, вдруг там куча всяких delay? ;)

dreamol
Offline
Зарегистрирован: 19.07.2016

Uno для эксперементов что было, купил еще Due но как выснил у него нет  EEPROM, пока на Uno потом переведу на мегу, код ниже.... 

В итоге я решил проблему. Решение: Не обрабатывать событие кнопки, а читать значение (через N секунд), и если оно изменилось выставлять угол.

#include <EEPROM.h>
#include <OneWire.h>
#include <Wire.h>
#include <SoftwareSerial.h>
#include <Nextion.h>
#include "Servo.h"

#define Temp_work 30 //Температура срабатывания вентиляторов
#define fanCtrlPin 5
OneWire ds(4);
Servo servoMain; // Объект Servo

SoftwareSerial nextion(2, 3);// Nextion TX to pin 2 and RX to pin 3 of Arduino
Nextion myNextion(nextion, 9600); //create a Nextion object named myNextion using the nextion serial port @ 9600bps


#define Temp_fan_work 30
#define Servo_pin 6

int q_on=0; //счетчик включений

byte t_real=0; // Текущая температура
byte t_max=0; //максимальная температура
byte t_min=0; //минимальная температура

int tm_all; //общее время работы минут
byte tmq_all; //общее время работы часов
int tm_1; //время работы минут
byte tmq_1; //Q время работы часов
int tm_2; //время работы минут
byte tmq_2; //Q время работы часов
int tm_3; //время работы минут
byte tmq_3; //Q время работы часов
int tm_4; //время работы минут
byte tmq_4; //Q время работы часов
int tm_5; //время работы минут
byte tmq_5; //Q время работы часов

unsigned int sec=1; //время работы секунд
unsigned int minut; //время работы минут
unsigned int chas; //время работы часов
unsigned int chas_q; //коэфицент часов

byte sec_work=0;
String temp="";
String messageNextion="";
int svet=20;

byte lowByte;
byte highByte;
          
void setup() {
Serial.begin(9600);
pinMode(fanCtrlPin, OUTPUT);
r_param_eeprom();
Serial.println(q_on);
Serial.println(t_max);
Serial.println(t_min);
Serial.println(tm_all);
Serial.println(tmq_all);
Serial.println(tm_1);
Serial.println(tmq_1);
Serial.println(tm_2);
Serial.println(tmq_2);
Serial.println(tm_3);
Serial.println(tmq_3);
Serial.println(tm_4);
Serial.println(tmq_4);
Serial.println(tm_5);
Serial.println(tmq_5);
q_on=q_on+1;
lowByte = ((q_on >> 0) & 0xFF);
highByte = ((q_on >> 8) & 0xFF);
EEPROM.write(100, lowByte);
EEPROM.write(101, highByte);
tm_all=tmq_all*10000+tm_all;
     
myNextion.init();
}

void loop() 
{
 
if (millis()%100==0) timecount ();
if ((sec%5==0)&&(millis()%100==0))
  {
    if ((sec%60==0)&&(sec_work!=sec)) { sec_work=sec; minut_work(); }
  }


if ((sec%1==0)&&(sec_work!=sec)) 
{ sec_work=sec; 
Servo_set ();
Temp_real ();
//if (servoMain.attached()==TRUE) servoMain.detach();
UpdateTFT();
//if (servoMain.attached()==FALSE) servoMain.attach(Servo_pin);

}


messageNextion = myNextion.listen();
if(messageNextion != "") Serial.println(messageNextion); 
 

  if ((messageNextion == "65 0 1 1 ffff ffff ffff")||(messageNextion == "65 0 2 1 ffff ffff ffff"))
    {
      //Servo_set ();
    }

}


void Servo_set ()
{
int t1=myNextion.getComponentValue("j0");
if (svet!=t1)
  {
     if (servoMain.attached()==FALSE) servoMain.attach(Servo_pin);
     svet=t1;
     servoMain.write(svet);
     delay (500);
     Serial.println(svet);
     servoMain.detach();
  }
}




void minut_work ()
{
          if (tm_all==10000)
            {
              tmq_all++;
              tm_all=0;
            }
          w_param_eeprom();
          Serial.println("*************** Update EEPROM *********************");


}



void Temp_real ()
{
byte data[2];
ds.reset(); 
ds.write(0xCC);
ds.write(0x44);
//delay(750);
ds.reset();
ds.write(0xCC);
ds.write(0xBE);
data[0] = ds.read(); 
data[1] = ds.read();
int Temp = (data[1]<< 8)+data[0];
Temp = Temp>>4;
t_real=Temp;
if (t_real>=Temp_fan_work) analogWrite(fanCtrlPin, 255);
else analogWrite(fanCtrlPin, 0);
if (t_real<t_min) t_min=t_real;
if (t_real>t_max) t_max=t_real;
}



void UpdateTFT()
{

          temp="Value ON: ";
          temp=temp + q_on;
          //Serial.println(temp);
          myNextion.setComponentText("T_q_on", String(q_on));

         
          temp="Temperature MAX: ";
          temp=temp + t_max;
          //Serial.println(temp);
          myNextion.setComponentText("T_max", String(t_max));
         
          temp="Temperature MIN: ";
          temp=temp + t_min;
          //Serial.println(temp);
          myNextion.setComponentText("T_min", String(t_min));
         
          temp="Temperature REAL: ";
          temp=temp + t_real;
          //Serial.println(temp);
          myNextion.setComponentText("T_real", String(t_real));

          
          temp="";
          temp=temp + "Worktime now: " + minut/60 + ":" + minut%60 + ":" + sec;
          //Serial.println(temp);
          myNextion.setComponentText("T_Worktime_now", temp);
          
          temp="";
          temp=temp + "Worktime all: " + (tm_all+minut)/60 + ":" + (tm_all+minut)%60;
          //Serial.println(temp);
          myNextion.setComponentText("T_Worktime_all", temp);
          
          //Serial.println("******************************************");

  
  
  
  
  

  
}

void timecount ()
{
sec = ((millis())/1000)%60;  
minut  = (((millis())/1000)/60);
//minut  = (((millis())/1000)/60)%60;
}

void r_param_eeprom()
{
lowByte = EEPROM.read(100);
highByte = EEPROM.read(101);
q_on = ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);

t_max=EEPROM.read(103);
t_min=EEPROM.read(104);


lowByte = EEPROM.read(105);
highByte = EEPROM.read(106);
tm_all = ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
tmq_all = EEPROM.read(107);

lowByte = EEPROM.read(110);
highByte = EEPROM.read(111);
tm_1 = ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
tmq_1 = EEPROM.read(112);

lowByte = EEPROM.read(113);
highByte = EEPROM.read(114);
tm_2 = ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
tmq_2 = EEPROM.read(115);

lowByte = EEPROM.read(116);
highByte = EEPROM.read(117);
tm_3 = ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
tmq_3 = EEPROM.read(118);

lowByte = EEPROM.read(119);
highByte = EEPROM.read(120);
tm_4 = ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
tmq_4 = EEPROM.read(121);

lowByte = EEPROM.read(122);
highByte = EEPROM.read(123);
tm_5 = ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
tmq_5 = EEPROM.read(124);


}

void w_param_eeprom()
{
lowByte = ((q_on >> 0) & 0xFF);
highByte = ((q_on >> 8) & 0xFF);
EEPROM.write(100, lowByte);
EEPROM.write(101, highByte);


EEPROM.write(103, t_max);
EEPROM.write(104, t_min);


lowByte = ((tm_all+minut >> 0) & 0xFF);
highByte = ((tm_all+minut >> 8) & 0xFF);

EEPROM.write(105,lowByte);
EEPROM.write(106,highByte);
EEPROM.write(107,tmq_all);

lowByte = ((tm_1 >> 0) & 0xFF);
highByte = ((tm_1 >> 8) & 0xFF);
EEPROM.write(110,lowByte);
EEPROM.write(111,highByte);
EEPROM.write(112,tmq_1);

lowByte = ((tm_2 >> 0) & 0xFF);
highByte = ((tm_2 >> 8) & 0xFF);
EEPROM.write(113,lowByte);
EEPROM.write(114,highByte);
EEPROM.write(115,tmq_2);

lowByte = ((tm_3 >> 0) & 0xFF);
highByte = ((tm_3 >> 8) & 0xFF);
EEPROM.write(116,lowByte);
EEPROM.write(117,highByte);
EEPROM.write(118,tmq_3);

lowByte = ((tm_4 >> 0) & 0xFF);
highByte = ((tm_4 >> 8) & 0xFF);
EEPROM.write(119,lowByte);
EEPROM.write(120,highByte);
EEPROM.write(121,tmq_4);

lowByte = ((tm_5 >> 0) & 0xFF);
highByte = ((tm_5 >> 8) & 0xFF);
EEPROM.write(122,lowByte);
EEPROM.write(123,highByte);
EEPROM.write(124,tmq_5);
}