UART и мигалка проблема в коде помогите улучшить код

Jomei
Offline
Зарегистрирован: 22.08.2014

Добрый день написал простенькую программку для управления  шима и мигалки по rs232 шим работает нормально от 0 до 250 управляю через rs232 а скорость мигалки не меняется  хотелось бы управлять скоростью мигалки  чтоб и шим и мигалка синхронна работали   

int motorPin = 5;
int led = 13; 
void setup() 
{ 
  pinMode(motorPin, OUTPUT);
  pinMode(led, OUTPUT);
  Serial.begin(9600);
} 
 
 
void loop() 
{ 
  if (Serial.available())
  {
    int speed = Serial.parseInt();
    if (speed >= 0 && speed <= 255)
    {
      analogWrite(motorPin, speed);
    }
    digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(motorPin);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(motorPin);   
  }
}

 

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

А че вообще код делает? Типа лепила из того что было, а потом долго руки мыла?

Jomei
Offline
Зарегистрирован: 22.08.2014

Нет мигалка будет управлять шаговым двигателем а шим подключон на чп частотник я уже настроил все работает отлично вот только проблема в мигалке  

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Она не мигает?

Jomei
Offline
Зарегистрирован: 22.08.2014

нет не мигает через ком отправляю значение один раз моргнет и все (

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Вот же печаль то какая. А если внимательно посмотреть на код. То там вообще не ясно почему оно должно мигать чаще 1 раза.

Jomei
Offline
Зарегистрирован: 22.08.2014

Я только начинаю изучать Arduino я чайник в этом ) и врядли  смогу найти ошибку в коде подскажите пожалуйста что я не так делаю ? 

An25
Offline
Зарегистрирован: 19.09.2014

В теле управляющего оператора if сидит вся ваша программа и запускается она только если Serial.available()>0 . Это значит что лампочка моргнет только когда Вы в очередной раз выведете что-то в порт. А моторчик конечно крутиться будет если его проинициализировать.

Еще советую вместо delay использовать конструкцию if millis() ...

что-то типа if millis()>=(oldmillis+delay) { PORTD ^= 1<<8}

Jomei
Offline
Зарегистрирован: 22.08.2014

An25 пишет:

В теле управляющего оператора if сидит вся ваша программа и запускается она только если Serial.available()>0 . Это значит что лампочка моргнет только когда Вы в очередной раз выведете что-то в порт. А моторчик конечно крутиться будет если его проинициализировать.

Еще советую вместо delay использовать конструкцию if millis() ...

что-то типа if millis()>=(oldmillis+delay) { PORTD ^= 1<<8}

спасибо огромное еще один вопрос а возможно ли два void loop написать что бы друг другу не мешали  чтоб и шим и моргалка брали одно значение  ?  зарание спасибо.

An25
Offline
Зарегистрирован: 19.09.2014

описать функцию loop можно и 10 раз но компилятор такое просто так не скомпилирует))) 

правильно вашу задачу решить с помощью прерываний. но пока вам рано, поэтому работайте с конструкцией if millis()>=

http://arduino.cc/en/Tutorial/BlinkWithoutDelay

 

int main(void)
{
    init();

    setup();

    for (;;)
        loop();

    return 0;
}

 

Jomei
Offline
Зарегистрирован: 22.08.2014

Не получается вообще (((

An25
Offline
Зарегистрирован: 19.09.2014

что именно?

а, пофиг на теорью, просто

1. вынесите 4 строки начинающиеся на d... за пределы оператора if {}

2. объявите speed в заголовке (сделате переменную глобальной)

3. в тех строках которые начинаются на d... переменную motorpin поменяйте на speed и 255-speed соответственно

leshak
Offline
Зарегистрирован: 29.09.2011

 delay(motorPin); - как, по вашему, что делает эта строка?

Jomei
Offline
Зарегистрирован: 22.08.2014
int ledPin = 13;
void setup() {
pinMode(ledPin, OUTPUT);
  Serial.begin(19200);
}
void loop() {
  int sensorValue = analogRead(A0);
  Serial.println(sensorValue);
  delay(100);
  digitalWrite(ledPin, HIGH);
  delay(analogRead(A0));
  digitalWrite(ledPin, LOW);
  delay(analogRead(A0));
}

здесь скорость мигалки управляю через ацп хотел как здесь сделать но только не через ацп а uart

 

leshak
Offline
Зарегистрирован: 29.09.2011

>здесь скорость мигалки управляю через ацп хотел как здесь сделать но только не через ацп а uart
Ну, дык а что вам мешает?

В изначальном посте у вас же есть пример. Как прочитать число в переменную из Serial. А потом эту переменую использовать со своими функциями.
Читать в переменную speed и потом использовать ее в функции analogWrite у вас получилось же.
Что мешает аналогично, сделать переменную, скажем pause и использовать ее с фунцией delay()?

leshak
Offline
Зарегистрирован: 29.09.2011

Кстати, в #13, зачем вам столько analogRead-дов? Вы же уже сохранили значение АЦП в переменную sensorValue. Почему ее не использовать?   delay(sensorValue);
Потом останется только заполнять sensorValue не через analogRead, а через serial.parseInt 

и все.

Jomei
Offline
Зарегистрирован: 22.08.2014

leshak пишет:

>здесь скорость мигалки управляю через ацп хотел как здесь сделать но только не через ацп а uart
Ну, дык а что вам мешает?

В изначальном посте у вас же есть пример. Как прочитать число в переменную из Serial. А потом эту переменую использовать со своими функциями.
Читать в переменную speed и потом использовать ее в функции analogWrite у вас получилось же.
Что мешает аналогично, сделать переменную, скажем pause и использовать ее с фунцией delay()?

как и я сказал я новичек и совсем не представляю как это сделать да и с русским у меня проблемы если что не так простите ) можете показать пример буду очен благодарен.

Jomei
Offline
Зарегистрирован: 22.08.2014

An25 пишет:

что именно?

а, пофиг на теорью, просто

1. вынесите 4 строки начинающиеся на d... за пределы оператора if {}

2. объявите speed в заголовке (сделате переменную глобальной)

3. в тех строках которые начинаются на d... переменную motorpin поменяйте на speed и 255-speed соответственно

так ?

int motorPin = 5;
int led = 2;
 
void setup() 
{ 
  pinMode(motorPin, OUTPUT);
  pinMode(led, OUTPUT);
  Serial.begin(9600);
} 
 
 
void loop() 
{ 
  if (Serial.available()) 
  {
    int speed = Serial.parseInt();
    if (speed >= 0 && speed <= 255)
    {
      analogWrite(motorPin, speed);
    }
    {
  digitalWrite(led, HIGH);  
  delay(speed);            
  digitalWrite(led, LOW);    
  delay(speed);              
}
  }
}

 

leshak
Offline
Зарегистрирован: 29.09.2011

>так ?

А чего вы меня спрашиваете? Проверте :) Мало ли кто чего на форуме насоветует.

Недостатки есть, но... ход мысли - верный.

 

An25
Offline
Зарегистрирован: 19.09.2014

1. int speed в шапку

2. int speed = Serial.parseInt() заменить на speed = Serial.parseInt()

3. в 25 строке напишите delay(255-speed);

4. надо вынести все что касается лампочки из под действия оператора if вроде вы это сделали но зачем там строки 27 и 28?

нет, там со скобками явная проблема... их много и они встречаются слишком часто )))

 

вместо 21 нарисуйте } а 27 и 28 удалите.

хотя я бы сделал по-другому.

leshak
Offline
Зарегистрирован: 29.09.2011

А недостаток в следующем: вы используете одну и ту же переменную и для скорости и для "какая пауза между миганиями".
Естественно из-за этого вы не сможете выставлять их "раздельно".
Вам нужно две переменные. Одну для скорости, другую для паузы. Я же писал: " сделать переменную, скажем pause"
Но.... вам тогда нужно будет, придумывать еще как отличать, что означает прочитанное с помощью parseInt число. Что это, скорость или пауза?  В какую переменную сохранять? Какой-то маркер, перед этим нужно слать значит... читать его....
По хорошему, именно так и нужно делать. Что-то типа

 

char marker=Serial.read();
if(marker=='s') speed=Serial.parseInt();
if(marker=='p') pause=Serial.parseInt();

и цифры свои слать уже в виде строк "s200" - установить скорость в 200, "p150" - установить паузу в 150.

Но.... если "пусть и криво, зато проще.." (меньше переделок от текущего). Можно вывернуться и по другому.
Обойтись, все-таки одной переменной.
Смотрите в свой код.... у вас же не любое число, для скорости, "принимается к исполнению". А только в интервале от 0 до 255.
Следовательно мы можем договорится что пришедшие числа "от 0 до 255" - это скорость, а все остальное - это паузы. И отличать их по этому признаку.
Что-бы еще проще.... мы можем считать, что "положительные числа означают скорость, а отрицательные - паузу".
Тогда делаем что-то типа

static int pause=100; // начальное значение паузы

if(speed<0){ // отрицательная скорость.. это не скорость, а пауза, нужно обновить переменную pause
   pause=-speed;  // обновляем pause не забывая превратить отрицательное число обратно в положительное
}

delay(pause);
.... ну и дальше пошло что было....

И теперь будем слать числа  типа:
"150" - установить скорость в 150
"-180" - установить паузу в 180

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

leshak
Offline
Зарегистрирован: 29.09.2011

An25 пишет:

1. int speed в шапку

2. int speed = Serial.parseInt() заменить на speed = Serial.parseInt()

Не помешает, но и не обязательно. Разницы в работе - не будет. analogWrite у нас вызывается только если пришло вменяемое число. А если не пришло, то... analogWrite "помнит" значение последнего вызова.

А вот delay() - таким "эффектом памяти" - не обладает. Вот тут уже однозначно пришлось бы применять ваш рецепт "в шапку".
Ну либо, использвоать ключевое слово static, как я и сделал в #20. Дает тот же эффект. Значение переменной не теряется между вызовами loop().
 

An25
Offline
Зарегистрирован: 19.09.2014

Все так.