Сервопривод
- Войдите на сайт для отправки комментариев
Пт, 29/07/2016 - 18:52
Добрый день, подскажите пожалуйста как решить проблему:
Имеется UNO к ней подключен дисплей Nextion, датчик DS18B20, компьтерный вентилятор и сервопривод FS90.
Так вот проблема: Сервопривод дрожит градусов на 5-10 при посылки данных на Nextion через UART, то есть у меня данные на дисплее обновляются кажные N секунд, так вот и сервопривод через каждые N секунд колеблется, после полебаний встает на заданный угол.
Что пробовал: Питание сервопривода подключал и напрямую и через отдельный блок питания, землю обьединял, пробовал через конденсаторы.
На другой пин тоже пробовал.
Вариант делать detach() перед обновлением экрана не подходит.
Если у кого была такая проблема, посоветуйте решение.
Прежде, чем найти решение, следует понять, в чем состоит проблема.
Дело в том, что управление сервой требует точно выдерживать длительность импульса. Подозреваю, что и для обмена с дисплеем точность временнЫх интервалов также должна выдерживатья достаточно строго.
Значит, что-то чему-то мешает.
Кстатит, как подключаете UART, если в Uno он уже занят USB?
И самое интересное, а почему Вы решили, что "делать detach() перед обновлением экрана не подходит"?
про UART не правильно указал, nextion подключен через 2 и 3 пин, серва на 6 пине.
detach() не подходит, потому что, на экране есть кнопки управления углом сервы, если в этот момент нажать кнопку серва не реагирует.
Правильно ли я понимаю, что используется SoftwareSerial?
Неочевидно, что он дружит с Servo.
Так что, вероятно, какую-то из библиотек придется переписывать.
Или заменить Uno на Mini с подключением Nextion через аппаратный Serial.
Или все-таки делать detach. Вряд ли обмен с дисплеем жрет заметный процент времени.
PS. Да, я не понял, почему "серва не реагирует"? Вы ведь опрашиваете состояние сенсорного экрана? Значит, можете обеспечить, чтобы сигнал на перемещение сервы проходил только тогода, когда серва подключена.
Собственно, подозрение, что проблема не в библиотеках (хотя могла бы быть), а во внутренней логике Вашей программы.
Код бы ещё глянуть, вдруг там куча всяких delay? ;)
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); }