Работа с беспроводным модулем APC220-43

vvadim
Offline
Зарегистрирован: 23.05.2012

Хочу попробовать дистанционно управлять двигателем с помощью модулей АРС220-43.

Имеются три параметра, которые снимаю с потенциометров.



int value1;
int value2;
int value3;

value1 = analogRead(A1);
value2 = analogRead(A2);
value3 = analogRead(A3);

Есть несколько кнопок, при нажатии на которые на приёмник передаются соответствующие им комбинации значений value1, value2 и value3. Как я понимаю, эти значения нужно записать в массивы для каждой кнопки. Подскажите, как правильно записать три параметра в массив для передачи через Serial а потом его прочитать. С передачей одного параметра разобрался, а вот с массивами столкнулся впервые.

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


#define TOTAL_VALUES 3 // сколько всего у нас кнопок
int values[TOTAL_VALUES];


void setup(){
  Serial.begin(57600);

  // читаем/заполняем массив
  for(byte i=0;i<TOTAL_VALUES;i++){
    values[i]=analogRead(A1+i);
  };
  

  
  // так Отсылаем в Serial
  Serial.write((byte*)values,sizeof(values));

}

void loop(){
  // а так читаем
  if(Serial.available()){ // жем пока что-то прийдет в Serial
     Serial.readBytes((char*)values,sizeof(values)); // вычитываем нужное количество байт
     
     // что-то делаем с прочитанными значениями
  }
}

 

P.S. непонятно причем тут безпроводный модуль? Ну то есть понятно что он есть в проекте, но вот к вопросу он явно отношения не имеет. Даже если все через него идет. Спросили-бы "как массив в Serial отправить". А тогда возможно и поиском бы что-то нашли ;)

vvadim
Offline
Зарегистрирован: 23.05.2012

Спасибо, будем пробовать.

vvadim
Offline
Зарегистрирован: 23.05.2012

Трудно разобраться. Так  будет более понятно











void loop(){
value1 = analogRead(A1);
value2 = analogRead(A2);
value3 = analogRead(A3);

if(digitalRead(button1Pin)==HIGH) 
{
  Serial.print ....отправляю value1
}
if(digitalRead(button2Pin)==HIGH) 
{
  Serial.print ....отправляю value1,value2
} 




if(digitalRead(button3Pin)==HIGH)
 { Serial.print ....отправляю value1,value2,value3 }

Потом читаю.




void loop(){
if(Serial.available())
{
if(Serial.read   читаю данные от кнопки1) 
{
  // делаю..............
}
if(Serial.read   читаю данные от кнопки2) 
{
  // делаю..............
}
if(Serial.read   читаю данные от кнопки3) 
{
  // делаю..............
}

 

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

>Трудно разобраться. Так  будет более понятно

Ну, во первых, вы просили "покажите как массив" - я показал "как массив".

Хотя, можно конечно, и по одному байту слать.

А так как вы показали, может и более понятно, да только работать не будет. Как минимум из-за использования print

Если хотите деталей (почему не print), то вот тут расписывал http://arduino.ru/forum/processing/serial-read#comment-25842

Там речь идет про arduino->processing, а у вас arduino->arduino, но суть проблемы будет та же самая.

Вообщем - вместо print используйте write.

 

А вообще, судя по вашему коду - есть подозрение что вы изначально задачу неправильно сформулировали и хотите что-то совсем другое (но что?). Попробуйте еще раз объяснить что именно вы хотите.

Или что именно "трудно разобратся".

Мне просто трудно понять, что же там трудного :) Строка 16-ть - пример как отсылается массив, строка 23 - как прочитать массив из сериал.

Чем и как вы заполните массив перед отсылкой - ваше дело. Так же как и что будете с ним делать после того как прочтете его из Serial.

Или массив тут вообще не нужен.... вообщем похоже что я просто не понимаю что вам нужно.

Может просто опишите, что за девайс делаете, в двух словах? Тогда легче будет понять что вам требуется.

 

 

vvadim
Offline
Зарегистрирован: 23.05.2012

Переработал схему управления шаговиком.

При подаче питания потенциометр управляет скоростью вращения.

Кнопка1 - на мотор передаются данные для 1 движения (скорость1, ускорение1, перемещение1)

Кнопка2 - на мотор передаются данные для 2 движения (скорость2, ускорение2, перемещение2)

Кнопка3 - на мотор передаются данные для 3 движения (скорость3, ускорение3, перемещение3)

Кнопка4 - опять управляю потенциометром. 

Как организовать правильно передачу такого количества данных через Serial я не знаю. По сети лазил, но ничего конкретного не нашёл. Массивы для меня тоже тёмный лес (может они и не нужны).

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

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

Про 

>Кнопка4 - опять управляю потенциометром. 

Не понял.

С первыми тремя - более/менее ясно.

Вопрос только в том эти эти "скорость/ускронеие/перемещение" - какого типа? В каком диапазоне они могут лежать? Проще всего гонять char/byte. Если же int, long и т.п. - уже чуток сложней (в понимании, в реализации - не сложней). Если же вы не уверены чем отличаются int от byte - то однозначно идти читать про типы. Без этого - вообще никак.

Предположим что они у нас byte. То есть могут принимать значение от 0 до 255.

Тогда отправка в принципе проста

if(НАЖАТА_КНОПКА_1){
   Serial.print("**"); // отправляем маркер начала передачи
   Serial.wirte(1); // сообщили что речь идет про мотор 1
   Serial.wirte(speed1); // отправили скорость1
   Serial.wirte(accel1); // отправили ускрорение1
   Serial.wirte(move1); // отправили перемещение1
}

Для остальных кнопок - аналогично

А читать примерно так:

if(Serial.avalaible()){
   char ch=Serial.read();
  if(ch=='*'){ // это первый символ маркера
     ch=Serial.read(); // читаем второй символ
    if(ch=='*'){ // это точно маркер, можно данные читать
        
        byte motorNo=Serial.read();// читаем номер мотора
        byte speed=Serial.read(); // читаем скорость
        byte  acel=Serial.read();// ускорение
       byte moveDelta=Serial.read();// перемещение

       // ну а тут уже, по motorNo решаете что делать с этими speed,acel,moveDelta
    }
 }
}

Примерно так. С хотя с массивами, как на меня, было бы понятей и компактней. Массив из 4-рех элементов. Первый элемент - номер мотора, остальные - ваши данные.

А еще более красиво - было-бы с использованием структур. Но боюсь сразу мозг взрывать :)  Хотя, постепенно может и до них дойдем.

Если данные не будет успевать "добегать", то возможно между всеми Serial.read() нужно будет еще натыкать

while(!Serial.available()){} // ждем пока в Serial появятся данные

P.S. Ну и надеюсь что ловить ловить нажатие кнопки, боротьяс с ее дребезгом - вы уже умеете. Если нет - читайте прикрепленную тему про кнопки.

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

А да.. забыл сказать что за маркер такой. Ну вот придумалось мне, перед данными, всегда посылать две звездочки. Типа как сигнал "счас данный пойдут". Что-бы если был перерыв в передаче, или вторая дуина включилась позже - она всегда могла определить где именно "начало пакет данных".

Вообщем игнорирует все пока не прийдут две ** - и за ними читает ровно четыре байта.

vvadim
Offline
Зарегистрирован: 23.05.2012

C дребезгом я уже  давно подружился. 

Данные int (до 1200).

А как тогда с управлением с помощью потенциометра  Serial.write(valPot)  и valPot = Serial.read(), где эта часть кода должна быть? Управление шаговым  двигателем потенциометром и кнопками разное.

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

Я уже сказал - я про потенциометр - нифига не понял. Поэтому "где это часть кода дожна быть" - сказать вам не могу.

Но общий подход все этой беды лучше делать таким.

Отдельно - читаем входы, заполняем в какие-то переменные (массивы, структуры e.t.c)

Отдельно - по отлову каких-то событий (нажатие кнопки, изменение состояние потенциометра и т.п.) - отправляем подготовленные данные в Serial.

Вообщем не мешать мухи и котлеты.

Данные int (до 1200).

А бы вам советовал, для начала все-таки огранчинится byte. Что-бы не взрывать мозг вот этим Запись в EEPROM | Аппаратная платформа Arduino  (там выясняли как разбирать int на байты).... хотя стоп. Это же ваша тема :)  Ну значит уже знаете.

Значит вместо Serial.wirte(speed1);  будете делать что-то типа Serial.wirte(speed1HiByte);Serial.wirte(speed1LowByte);

Вообщем, на самом деле, все довольон похоже на то как вы с eeprom работали. И кстати такие же   read/write использовать. Только адресов нет.

А можно не разбиратся, слать int тем же способом как и массив в сообщении #1. 

Но.. я бы все-таки для начала/простоты предложил потренироватся с байтами (ну потеряете точность, будет немного "скачками" менятся). Зарабоатет - потому будете полировкой заниматся.

Перейти к байтам вам поможет функция map. На отправляющий делаете, перед отправкой, map(value,0,1200,0,255)  , а на принимающей обратно востанавливаете диапазон map(readedValue,0,255,0,1200)

 

vvadim
Offline
Зарегистрирован: 23.05.2012

leshak пишет:

Тогда отправка в принципе проста







if(НАЖАТА_КНОПКА_1){
   Serial.print("**"); // отправляем маркер начала передачи
   Serial.wirte(1); // сообщили что речь идет про мотор 1
   Serial.wirte(speed1); // отправили скорость1
   Serial.wirte(accel1); // отправили ускрорение1
   Serial.wirte(move1); // отправили перемещение1
}

Для остальных кнопок - аналогично

А читать примерно так:







if(Serial.avalaible()){
   char ch=Serial.read();
  if(ch=='*'){ // это первый символ маркера
     ch=Serial.read(); // читаем второй символ
    if(ch=='*'){ // это точно маркер, можно данные читать
        
        byte motorNo=Serial.read();// читаем номер мотора
        byte speed=Serial.read(); // читаем скорость
        byte  acel=Serial.read();// ускорение
       byte moveDelta=Serial.read();// перемещение

       // ну а тут уже, по motorNo решаете что делать с этими speed,acel,moveDelta
    }
 }
}

 

А как быть  если при нажатии разных кнопок передаётся разное количество данных. Например при нажатии кнопки А передаётся 5 байт( два параметра плюс маркер ), а при нажатии кнопки В передаётся 7 байт( четыре параметра плюс маркер).  Как организовать чтение данных в таком случае?

maksim
Offline
Зарегистрирован: 12.02.2012

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

vvadim
Offline
Зарегистрирован: 23.05.2012

Подскажите, правильно ли записал чтение пакета

 



if ( Serial.available() > 0) { 
  char inByte = Serial.read(); 
  if (inByte == '*') { 
    int len = 3; 
    char inString[len]; 
    for (int i = 0; i < len; i++) {
      inString[i] = Serial.read();
    }
    motorNo=Serial.read();     // читаем номер мотора
    mspeed=Serial.read();      // читаем скорость
    aсcel=Serial.read();       // ускорение
    moveDelta=Serial.read();   // перемещение
  }
}


 

Ikegammy
Offline
Зарегистрирован: 23.10.2013

Продолжение в студию!!!)))

maksim
Offline
Зарегистрирован: 12.02.2012

Непонятен смысл строк с 4 по 8, а правильно или нет вы читаете зависит от того как вы отправляете пакет. Так же между каждым Serial.read() рекомендую ставить задержку иначе байты не будут успевать приходить и вы будете читать пустой буфер или нужно дождаться необходимого количества байт - if (Serial.available() >= 8)

Ikegammy
Offline
Зарегистрирован: 23.10.2013

To Maksim помогите разобраться!!! очень много гуглил и яндоксил но немогу ни как понять, как это работает 

по порядку 

1) есть две ардуины мега, на одну передатчик заведенны джойстики (переменные резисторы), а на вторую приемник драйверы ДС движков!!!

2) есть вот это т скетч  предоставленный vvadimom 


// X axis is A0
 // Y axis is A1
 #define switchPin 2 // switch input
 #define motor1Pin 3 // Motor 1 leg 1 (pin 2, 1A)
 #define motor2Pin 4 // Motor 1 leg 2 (pin 7, 2A)
 #define motor3Pin 6 // Motor 2 leg 1
 #define motor4Pin 7 // Motor 2 leg 2
 #define enable1Pin 9 // Motor1 enable pin
 #define enable2Pin 10 // Motor2 enable pin
 #define ledPin 13 // Reset LED
 #define slack 50 // Slack in joystick
 float joy0;  // Defines scaling factor for joystick A0
 float joy1;  // Defines scaling factor for joystick A1
 float joyA0; // Defines starting position of X axis
 float joyA1; // Defines starting position of Y axis
 void setup()
 {
         // Sets scaling factors at program start
         joy0 = 1023/analogRead(A0);
         joy1 = 1023/analogRead(A1);
         // Determines and reads starting positions of X and Y axis
         joyA0 = analogRead(A0);
         joyA1 = analogRead(A1);
         
         // set the switches as an input:
 pinMode(switchPin, INPUT);
 // set all the other pins you're using as outputs:
 pinMode(motor1Pin, OUTPUT);
 pinMode(motor2Pin, OUTPUT);
 pinMode(motor3Pin, OUTPUT);
 pinMode(motor4Pin, OUTPUT);
 pinMode(enable1Pin, OUTPUT);
         pinMode(enable2Pin, OUTPUT);
 pinMode(ledPin, OUTPUT);
         
         // set enablePin high so that motor can turn on:
  
 // blink the LED 3 times. This should happen only once.
 // if you see the LED blink three times, it means that the module
 // reset itself,. probably because the motor caused a brownout
 // or a short.
 blink(ledPin, 3, 100);
         Serial.begin(9600);   //Turn on the Serial Port at 9600 bps
 }
 void loop()
 {
         // Reads position of A0 and A1 (X and Y axis)
         int stickX = analogRead(A0);
         int stickY = analogRead(A1);
   
         // Reads the position of A0 and determines direction and speed
         if (stickX < joyA0-slack)
         {
           analogWrite(enable1Pin, abs(stickX-510)/2);
           digitalWrite(motor1Pin, HIGH); // set leg 1 of the Motor1 high
   digitalWrite(motor2Pin, LOW); // set leg 2 of the Motor1 low
         }
         if (abs( stickX - joyA0 ) < slack)  // Sets deadspace on stick
         {
           digitalWrite(enable1Pin, LOW);
         }
         if (stickX > joyA0+slack)
         {
           analogWrite(enable1Pin, (stickX-512)/2);
           digitalWrite(motor1Pin, LOW); // set leg 1 of the Motor1 low
          digitalWrite(motor2Pin, HIGH); // set leg 2 of the Motor1 high
         }
         
         // Reads the position of A1 and determines direction and speed
         if (stickY < joyA1-slack)
         {
           analogWrite(enable2Pin, abs(stickY-510)/2);
           digitalWrite(motor3Pin, HIGH); // set leg 1 of the Motor2 high
   digitalWrite(motor4Pin, LOW); // set leg 2 of the Motor2 low
         }
         if (abs(stickY - joyA1) < slack)  // Sets deadspace on stick
         {
           digitalWrite(enable2Pin, LOW);
         }
         if (stickY > joyA1+slack)
         {
           analogWrite(enable2Pin, (stickY-513)/2);
           digitalWrite(motor3Pin, LOW); // set leg 1 of the Motor2 low
   digitalWrite(motor4Pin, HIGH); // set leg 2 of the Motor2 low
        }
 }
 //blinks an LED
 void blink(int whatPin, int howManyTimes, int milliSecs)
 {
 int i = 0;
 for ( i = 0; i < howManyTimes; i++)
 {
  digitalWrite(whatPin, HIGH);
  delay(milliSecs/2);
  digitalWrite(whatPin, LOW);
  delay(milliSecs/2);
 }
 }

как передат по сериал значение с джойстика!!!!! и не сильно переделывать скетч!!

я нуб но очень интересно чтоб это заработало!!

maksim
Offline
Зарегистрирован: 12.02.2012
#define preamble 0b01010101
#define motor1Bit 0b00000001
#define motor2Bit 0b00000010
#define motor3Bit 0b00000100
#define motor4Bit 0b00001000
#define motorsByte  1
#define enable1Byte 2
#define enable2Byte 3

#define ledPin 13 // Reset LED
#define slack 50 // Slack in joystick

int joyX;  // Defines scaling factor for joystick A0
int joyY;  // Defines scaling factor for joystick A1

void setup()
{
  delay(100);
  joyX = analogRead(A0);
  joyY = analogRead(A1);

  pinMode(ledPin, OUTPUT);

  Blink(ledPin, 3, 100);
  Serial.begin(9600);  
}


void loop()
{
  int stickX = analogRead(A0);
  int stickY = analogRead(A1);

  byte packet[4] = {preamble, 0, 0, 0};
  
  if (abs(stickX-joyX) < slack) packet[enable1Byte] = 0;
  else if (stickX < joyX-slack)
  {
    packet[enable1Byte] = constrain(abs(stickX-510)/2, 0, 255);
    packet[motorsByte] |= motor1Bit;
  }
  else if (stickX > joyX+slack)
  {
    packet[enable1Byte] = constrain(abs(stickX-510)/2, 0, 255);
    packet[motorsByte] |= motor2Bit;
  }


  if (abs(stickY - joyY) < slack) packet[enable2Byte] = 0;
  else if (stickY < joyY-slack)
  {
    packet[enable2Byte] = constrain(abs(stickY-510)/2, 0, 255);
    packet[motorsByte] |= motor3Bit;
  }
  else if (stickY > joyY+slack)
  {
    packet[enable2Byte] = constrain(abs(stickY-510)/2, 0, 255);
    packet[motorsByte] |= motor4Bit;
  }


  Serial.write(packet, 4);
  
  delay(50);
}


void Blink(byte whatPin, int howManyTimes, int milliSecs)
{
  for (int i = 0; i < howManyTimes; i++)
  {
    digitalWrite(whatPin, HIGH);
    delay(milliSecs/2);
    digitalWrite(whatPin, LOW);
    delay(milliSecs/2);
  }
}

 

#define motor1Pin 3 // Motor 1 leg 1 (pin 2, 1A)
#define motor2Pin 4 // Motor 1 leg 2 (pin 7, 2A)
#define motor3Pin 6 // Motor 2 leg 1
#define motor4Pin 7 // Motor 2 leg 2
#define enable1Pin 9 // Motor1 enable pin
#define enable2Pin 10 // Motor2 enable pin

#define ledPin 13 // Reset LED

#define preamble 0b01010101
#define motor1Bit 0b00000001
#define motor2Bit 0b00000010
#define motor3Bit 0b00000100
#define motor4Bit 0b00001000
#define motorsByte  0
#define enable1Byte 1
#define enable2Byte 2

void setup()
{
  pinMode(motor1Pin, OUTPUT);
  pinMode(motor2Pin, OUTPUT);
  pinMode(motor3Pin, OUTPUT);
  pinMode(motor4Pin, OUTPUT);
  pinMode(enable1Pin, OUTPUT);
  pinMode(enable2Pin, OUTPUT);
  pinMode(ledPin, OUTPUT);

  Blink(ledPin, 3, 100);
  Serial.begin(9600);  
}


void loop()
{

  if (Serial.available() && Serial.read() == preamble) 
  {
    uint32_t timeout = millis();
    while((Serial.available() < 3) && (millis()-1000 < timeout));
    if(millis()-1000 < timeout)
    {
      byte packet[3];
      for(byte i = 0; i < 3; i++) packet[i] = Serial.read();

      digitalWrite(motor1Pin, packet[motorsByte]&motor1Bit); // set leg 1 of the Motor1
      digitalWrite(motor2Pin, packet[motorsByte]&motor2Bit); // set leg 2 of the Motor1
      digitalWrite(motor3Pin, packet[motorsByte]&motor3Bit); // set leg 1 of the Motor2
      digitalWrite(motor4Pin, packet[motorsByte]&motor4Bit); // set leg 2 of the Motor2

      analogWrite(enable1Pin, packet[enable1Byte]);
      analogWrite(enable2Pin, packet[enable2Byte]);
    }
  }

}


void Blink(byte whatPin, int howManyTimes, int milliSecs)
{
  for (int i = 0; i < howManyTimes; i++)
  {
    digitalWrite(whatPin, HIGH);
    delay(milliSecs/2);
    digitalWrite(whatPin, LOW);
    delay(milliSecs/2);
  }
}

 

Ikegammy
Offline
Зарегистрирован: 23.10.2013

ОГРОМНОЕ СПАСИБО !!!!!!!!