Прием данных в ардуино через Serial port
- Войдите на сайт для отправки комментариев
Ср, 17/10/2012 - 18:10
Пытаюсь отправить массив данных через сериал порт из 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
В 20 строке вы объявили статический массив int Str[0] размером ноль компонентов, то есть в ваш массив адекватно ничего нельзя записать, куда вы на самом деле записываете принятые данные сказать трудно, а читаете из массива мусор - это по дуине.
Я не разбираюсь в VB но в 22 строчке по-моему вы отправляете не массив recievdata, а строку "recievdata"
Так я же потом в 26 строке с помощью цикла увеличиваю размер массива
Вы не увеличиваете размер массива, а обращаетесь к несуществующему элементу массива. И я не понимаю к чему эта упертость? Прочитайте что такое массив в СИ и как с ним работать.
Я прочитал, но как туда записать данные из serial я не могу понять. Не могли бы Вы подсказать как это лучше сделать? Даже если я задаю массив размером 3, даннные все-равно не приходят.
Значит проблема на передающей стороне.
Вот пример, если из сериал-монитора отправить 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]); } }Спасибо, все заработало!
Вот видео как работает программа при отправке данных в 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 } } }Я вот только одного не пойму, зачем в этой строке в конце вычитается '0' ?
for (int i = 0; i < 4; i++) Str[i] = Serial.read() - '0';
Погуглите про коды ASCII и почитайте про типы данных в разделе Программирование
привет, не стал делать отдельную тему напишу тут.. нужен совет
имею 4 числа float но естественно можно и int допустим (x1=12.54 x2 = 13.48 x3 = 125.7 x4 = 152.8)
нужно передать их с одной ардуины на другую через софтваресериал (модули HC-12) (расстояние 500м прямая видимость)
как лучше передавать данные? отдельно каждое число или как-то можно всё это засунуть в один пакет и передать и как-то потом его распаковать? мне почему-то кажеть так будет надежней
данные передаються раз в минуту не чаще..
пока что сделал разбивку каждого числа на 2 байта а потом их собираю.. но не всегда корректно выходит(
Почитайте что-нибудь про коды Рида-Соломона.
Почитайте что-нибудь про коды Рида-Соломона.
это хорошее решение, а для восстановления можно ввести дополнительную избыточность, для unsigned int Сделав к первым двум XOR и передать три байта, тоже со второй парой,для обратного преобразование XOR между любыми двумя в тройке даёт третий элемент, седьмым элементом ввести CRC
что-то совсем хитрое.. лучше подскажите как эти 4 числа в одно запихнуть и передать одним пакетом.. а то у меня сейчас 8 пакетов идут.. и это не норм как считаю..