Здравствуйте. Используя плату Iteaduino UNO собрал схему где потенциометром меняю угол сервопривода и хочу видеть цифру этого угла на дисплее который работает по серийному порту. Однако во время передачи данных на LCD сервомотор почему-то начинает дёргаться, совершает какие-то лишние движения. По отдельности с переменным резистором и тот и другой прибор работают нормально. Пробовал внешнее питание делать и это не помогло. В чём может быть причина такого странного влияния LCD на серводвигатель? Заранее благодарен за ответ.
Код моей программы был получен объединением двух стандартных примеров IDE оболочки: Servo>Knob и SerialLCD>HelloWorld #include <Servo.h> #include <SerialLCD.h> #include <SoftwareSerial.h> //this is a must Servo myservo; // create servo object to control a servo SerialLCD slcd(0,1);//this is a must, assign soft serial pins int potpin = 0; // analog pin used to connect the potentiometer int val, itog, num; // variable to read the value from the analog pin void setup() { myservo.attach(9); // attaches the servo on pin 9 to the servo object slcd.begin(); // Print a message to the LCD. slcd.print("hello, world!"); } void loop() { val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023) itog = map(val, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180) myservo.write(itog); // sets the servo position according to the scaled value slcd.setCursor(0, 1); slcd.print(itog, DEC); delay(50);} Вся эта писанина заставляет серводвигатель дёргаться как паралитика. Частота дёрганий напрямую связана с частотой моргания светодиода передачи информации на дисплей. Приходится делать разные ухищрения, которые тем не менее не приводят к нормальной работе связки.
Сервопривод управляется таймерами по прерываниям. Если кто-то ещё пользуется прерываниями, то будут возникать ситуации, когда сервопривод уже нуждо дёрнуть, но в данный момент другое прерывпние уже обрабатывается. Тайминги съезжают и привет. Самое надёжное решение - это использовать отдельный контроллер для управления сервами. Почитайте про Multiservo shield. Он эту проблему решает.
Не знаю. как там у вас, а у меня всё работает нормально Код (Text): #include <Servo.h> #include <Wire.h> #include <LCD.h> #include <LiquidCrystal_I2C.h> #define LCD_I2C_ADDR 0x20 #define BACKLIGHT 6 #define LCD_EN 4 #define LCD_RW 5 #define LCD_RS 6 #define LCD_D4 0 #define LCD_D5 1 #define LCD_D6 2 #define LCD_D7 3 LiquidCrystal_I2C lcd(LCD_I2C_ADDR,LCD_EN,LCD_RW,LCD_RS,LCD_D4,LCD_D5,LCD_D6,LCD_D7); int potpin = A0; int val; Servo myservo; void setup() { myservo.attach(3); lcd.begin (16,2); analogWrite(BACKLIGHT, 100); lcd.clear(); } void loop() { val = analogRead(potpin); val = map(val, 0, 1023, 0, 179); myservo.write(val); lcd.setCursor ( 0, 0 ); lcd.print(val); lcd.print(" "); }
Как говорится, найдите десять отличий. Одно я уже вижу: #include <SoftwareSerial.h>. Оно не может быть причиной? Там ведь куча каких-то действий, сопровождающихся запретом прерываний.
Думаю, что без прерываний при наличии сервоприводов у человека LCD не заработает, т.к. сервоприводы будут вклиниваться в передачу и портить формат посылок. Тут решением был бы переход на аппаратный Serial (который так и называется). Только придётся тогда каждый раз отсоединять дисплей, чтобы прошить плату.
У вас не используется ни одна библиотека, работающая с прерываниями, кроме Servo. Т.ч. сервам никто не мешает
Так зачем морочить себе голову с библиотекой, которая использует прерывания. Топикстартер в программировании слабоват, вот пусть пока и играется с более простыми ситуациями. Ну а если ему хочется помазохизмничать, то зачем это на форум выносить. Всё равно никто не будет для него этим гемором заниматься
А нигде не написано, что SoftwareSerial какая-то плохая библиотека. Новичку об этом узнать неоткуда. Вот он и обратился на форум, мы ему рассказали, что SoftwareSerial с Servo несовместимы.