Прием данных в ардуино через Serial port

dcl
Offline
Зарегистрирован: 02.10.2012

 Пытаюсь отправить массив данных через сериал порт из Visuai Basic в Arduino но почему-то данные не доходят, подскажите правильно ли я все написал? При успешной передаче данных должны зажигаться подключенные к микрокомпьютеру три светодиода, но этого почему-то не происходит.

Код для Arduino:

int ledPin1 = 9; //присвоение переменной ledPin1 целого значения "9"
int ledPin2 = 8;
int ledPin3 = 7;



void setup()
{
  Serial.begin(9600); //открывает последовательный порт, устанавливает скорость 9600 бит/с
  pinMode(ledPin1, OUTPUT); //устанавливает режим работы выхода 9 ардуино как "выход"
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  
}

void loop()

{

int Str[0]; 



  if (Serial.available() > 2)  
 {  
 for (int i=0; i < 4; i++)
 {
   Str[i] = Serial.read(); 
 } 

int x=Str[0];
int y=Str[1];
int z=Str[2];

// дальше все работает
  if (x == 1) //если переменная val = 1
{
  digitalWrite(ledPin1, HIGH); //подается 5V на ledPin1
}
  if (x == 0) //иначе, если значение переменноц  val = 0
{
  digitalWrite(ledPin1, LOW); //снимается 5V с ledPin1
}
 if (y == 1) //если переменная val = 1
{
  digitalWrite(ledPin2, HIGH); //подается 5V на ledPin1
}
  if (y == 0) //иначе, если значение переменноц  val = 0
{
  digitalWrite(ledPin2, LOW); //снимается 5V с ledPin1
}
 if (z == 1) //если переменная val = 1
{
  digitalWrite(ledPin3, HIGH); //подается 5V на ledPin1
}
  if (z == 0) //иначе, если значение переменноц  val = 0
{
  digitalWrite(ledPin3, LOW); //снимается 5V с ledPin1
}
  }
  }

  
    

Код для Visual Basic

Imports System.IO
Imports System.IO.Ports
Imports System.Threading
Public Class Form1
    Shared _continue As Boolean
    Shared serialPort1 As New SerialPort
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        SerialPort1.Close()
        SerialPort1.PortName = "com3" 'change com port to match your Arduino port
        SerialPort1.BaudRate = 9600
        SerialPort1.DataBits = 8
        SerialPort1.Parity = Parity.None
        SerialPort1.StopBits = StopBits.One
        SerialPort1.Handshake = Handshake.None
        SerialPort1.Encoding = System.Text.Encoding.Default 'very important!
    End Sub


    Private Sub Button2_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim recievdata = {0, 1, 3}
        serialPort1.Open()
        serialPort1.Write("recievdata")
        
        serialPort1.Close()
    End Sub


End Class

 

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

 В 20 строке вы объявили статический массив int Str[0] размером ноль компонентов, то есть в ваш массив адекватно ничего нельзя записать, куда вы на самом деле записываете принятые данные сказать трудно, а читаете из массива мусор - это по дуине.
Я не разбираюсь в VB но в 22 строчке по-моему вы отправляете не массив recievdata, а строку "recievdata"

dcl
Offline
Зарегистрирован: 02.10.2012

Так я же потом в 26 строке с помощью цикла увеличиваю размер массива

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

Вы не увеличиваете размер массива, а обращаетесь к несуществующему элементу массива. И я не понимаю к чему эта упертость? Прочитайте что такое массив в СИ и как с ним работать.

dcl
Offline
Зарегистрирован: 02.10.2012

Я прочитал, но как туда записать данные из serial я не могу понять. Не могли бы Вы подсказать как это лучше сделать? Даже если я задаю массив размером 3, даннные все-равно не приходят.

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

Значит проблема на передающей стороне.

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

 Вот пример, если из сериал-монитора отправить 001 (ASCII), то загорится светодиод на ledPin3.

#define ledPin1 9 //присвоение переменной ledPin1 целого значения "9"
#define ledPin2 8
#define ledPin3 7

void setup(){
  Serial.begin(9600); //открывает последовательный порт, устанавливает скорость 9600 бит/с
  pinMode(ledPin1, OUTPUT); //устанавливает режим работы выхода 9 ардуино как "выход"
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT); 
}

void loop(){
  if (Serial.available() > 2){ 
    boolean Str[3];  
    for (int i = 0; i < 4; i++) Str[i] = Serial.read() - '0';
    digitalWrite(ledPin1, Str[0]);
    digitalWrite(ledPin2, Str[1]);
    digitalWrite(ledPin3, Str[2]);
  }
}

 

dcl
Offline
Зарегистрирован: 02.10.2012

 Спасибо, все заработало!

Вот видео как работает программа при отправке данных в serial порт.

Код программы:

int ledPin1 = 9; 
int ledPin2 = 8;
int ledPin3 = 7;

void setup()
{
  Serial.begin(9600); //открывает последовательный порт, устанавливает скорость 9600 бит/с
  pinMode(ledPin1, OUTPUT); 
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  
}

void loop()

{

      if (Serial.available() > 2){

    boolean Str[3]; 

    for (int i = 0; i < 4; i++) Str[i] = Serial.read() - '0';
  

int x=Str[0];
int y=Str[1];
int z=Str[2];
Serial.print(x);
Serial.print(y);
Serial.print(z);
Serial.flush();
      
  if (x == 1) //если переменная val = 1
{
  digitalWrite(ledPin1, HIGH); //подается 5V на ledPin1
}
  if (x == 0) //иначе, если значение переменноц  val = 0
{
  digitalWrite(ledPin1, LOW); //снимается 5V с ledPin1
}
 if (y == 1) //если переменная val = 1
{
  digitalWrite(ledPin2, HIGH); //подается 5V на ledPin1
}
  if (y == 0) //иначе, если значение переменноц  val = 0
{
  digitalWrite(ledPin2, LOW); //снимается 5V с ledPin1
}
 if (z == 1) //если переменная val = 1
{
  digitalWrite(ledPin3, HIGH); //подается 5V на ledPin1
}
  if (z == 0) //иначе, если значение переменноц  val = 0
{
  digitalWrite(ledPin3, LOW); //снимается 5V с ledPin1
}
  }
  }

  
    

 

dcl
Offline
Зарегистрирован: 02.10.2012

Я вот только одного не пойму, зачем в этой строке в конце вычитается '0' ?

for (int i = 0; i < 4; i++) Str[i] = Serial.read() - '0';

 

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

Погуглите про коды ASCII и почитайте про типы данных в разделе Программирование

kvazi
Offline
Зарегистрирован: 06.10.2016

привет, не стал делать отдельную тему напишу тут.. нужен совет

имею 4 числа float но естественно можно и int   допустим (x1=12.54 x2 = 13.48 x3 = 125.7 x4 = 152.8)

нужно передать их с одной ардуины на другую через софтваресериал (модули HC-12) (расстояние 500м прямая видимость)

как лучше передавать данные? отдельно каждое число или как-то можно всё это засунуть в один пакет и передать и как-то потом его распаковать? мне почему-то кажеть так будет надежней

данные передаються раз в минуту не чаще..

пока что сделал разбивку каждого числа на 2 байта а потом их собираю.. но не всегда корректно выходит(

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

Почитайте что-нибудь про коды Рида-Соломона.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

andriano пишет:

Почитайте что-нибудь про коды Рида-Соломона.

это хорошее решение, а для восстановления можно ввести дополнительную избыточность, для unsigned int Сделав к первым двум XOR и передать три байта, тоже со второй парой,для обратного преобразование XOR между любыми двумя в тройке даёт третий элемент, седьмым элементом ввести CRC

kvazi
Offline
Зарегистрирован: 06.10.2016

что-то совсем хитрое.. лучше подскажите как эти 4 числа в одно запихнуть и передать одним пакетом.. а то у меня сейчас 8 пакетов идут.. и это не норм как считаю..