Прием данных из COM порта - прошу помощи.
- Войдите на сайт для отправки комментариев
Приветствую дорогие форумчане!
Делаю интерактивную игрушку с сыном, нам необходимо включать определенные светодиоды на ардуино по команде компьютера через COM порт.
80 светодиодов, 8 сдвиговых регистров 74HC595, защелка каждого регистра подключена на отдельный выход ардуино, Arduino UNO .
После того как мы на простейшем примере научились управлять светодиодом через COM порт и научились управлять сдвиговыми регистрами(так же на примерах). Было решено это все соединить воедино.Мысли такие:
1) С компа отправляем команду: "R1,00000001"- где "R1"- номер регистра(номер пина ардуино к которому подключена защелка первого регистра), "00000001"- включаемый светодиод(двоичное число, его можно заменить десятичным)
2) Ардуино слушает COM порт, полученную команду записывает в буфер, из буфера сначала отделяет номер регистра, а потом записывает на этот регистр число которое соответствует включенным светодиодам.
Другие регистры не изменяют своего состояния(мы их защелки не дергаем) вот ссылки на примеры из сети которые я питаюсь адаптировать под себя, но ничего не выходит
http://forum.amperka.ru/threads/%D0%9E%D1%80%D0%B3%D0%B0%D0%BD%D0%B8%D0%...
А вот мой код в котором я могу выбирать нужный регистр, но не могу записывать число из COM порта, в принципе понимаю что не очень сложно осталось доделать но компилятор выдает ошибки(((
/*Опыт № 10 Папа и Ярик программируют дуню*/
#include <SPI.h>//подкл. библиотеку
enum { REG0 = 8, REG1 = 7 };//назначаем каждому регистру выходы выбора
/* функция записи в регистр */
void writeShiftRegister(int ss_pin, uint8_t value)
{
digitalWrite(ss_pin, LOW);
SPI.transfer(value);
digitalWrite(ss_pin, HIGH);
}
int val; // освобождаем память в контроллере для переменой
int numberREG[] = {REG0, REG1};//массив с номерам регистров для выбора
void setup()
{
Serial.begin(9600); // подключаем последовательный порт
SPI.begin();//инициализ. последов. шины
/* объявляем пины регистров как выходы */
pinMode(REG0, OUTPUT);
pinMode(REG1, OUTPUT);
/* обнуляем регистры*/
writeShiftRegister(REG0, 0);
writeShiftRegister(REG1, 0);
}
void loop()
{
if (Serial.available()) // проверяем, поступают ли какие-то команды
{
val = Serial.read(); // переменная val равна полученной команде
if (val == '0') {writeShiftRegister(REG0, 3);} // при 0 записываем на регистр число
if (val == '1') {writeShiftRegister(REG1, 55);} // при 1 записываем на регистр число
if (val == 'f') {writeShiftRegister(REG0, 0), writeShiftRegister(REG1, 0);} // при f обнуляем регистры
}
}
остается написать функцию которая будет из сообщения COM порта брать номер регистра и записывать в него десятичное число.
Помогите пожалуйста дописать код, немного осталось)))
ищите на форуме scanf() от ЕвгенияП
ищите на форуме scanf() от ЕвгенияП
Спасибо за ответ, читал тему про эту функцию, но не дошло до меня , еще пойду попробую)))
Вы хотите организовать на SPI ? Под шилд http://arduinolearning.com/code/multi-function-shield-examples.php
/*Seg_displ_A.ino каскад из 2х 74РС595N (POS - '0' SEG) Latch->4;(Latch_pin) ->10 CLK->7(CLK_pin) ->13 DI=8(DI_pin) ->11 */ //---------------------Cl_wire----------------------- #include <SPI.h> class Cl_wire { byte Latch_pin; byte max_device ; public: byte * buffer; Cl_wire(byte a, byte b): Latch_pin (a), max_device(b) { buffer = new byte[max_device]; } // setup setup() { SPI.begin(); pinMode(Latch_pin, OUTPUT); digitalWrite(Latch_pin, LOW); for (int j = max_device - 1; j >= 0; --j ) SPI.transfer(buffer[j] = 0x00); digitalWrite(Latch_pin, HIGH); } // запись void Write(byte adr, byte data) { buffer[adr] = data; digitalWrite(Latch_pin, LOW); for (int j = max_device - 1; j >= 0; --j ) SPI.transfer(buffer[j]); digitalWrite(Latch_pin, HIGH); } // запись 2-х байт void Write2byte(byte adr1, byte data1, byte adr2, byte data2) { buffer[adr1] = data1; buffer[adr2] = data2; digitalWrite(Latch_pin, LOW); for (int j = max_device - 1; j >= 0; --j ) SPI.transfer(buffer[j]); digitalWrite(Latch_pin, HIGH); } }; //------------------------Cl_74HC595H------------------- const byte Segment_font[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0X80, 0X90};//LOW const byte Pos_font[] = {0xF8, 0xF4, 0xF2, 0xF1}; // HIGH class Cl_74HC595H { Cl_wire *wire;//шина byte adr_p; // адрес ответ за позицию byte adr_s; // адрес ответ за цифру uint16_t data;// число на дисплее uint32_t past; byte i = 0; public: // конструктор Cl_74HC595H(Cl_wire *_wire, byte _adr_p, byte _adr_s): wire(_wire), adr_p(_adr_p), adr_s(_adr_s) {} void setup() { wire->Write2byte(adr_p, 0x00, adr_s, 0xFF); } void write(byte pos, byte data) { wire->Write2byte(adr_s, Segment_font[data], adr_p, Pos_font[pos]); } void write(uint16_t _data) { data = _data; } void loop() { write(0, data % 10); write(1, data / 10 % 10); write(2, data / 100 % 10); write(3, data / 1000 % 10); } }; //------------------------------------------------------------ Cl_wire wire(4, 20); //Cl_wire wire(4, 7, 8, 20); Cl_74HC595H Pos(&wire, 0, 1); void setup () { wire.setup(); Pos.setup(); Pos.write(1234); } void loop() { Pos.loop(); }Есть еще скетч Пакет здесь https://yadi.sk/d/WaW7iUgj3GPUvp
/*Wire_74HC595.ino */ const int Latch_pin = 3; const int CLK_pin = 4; const int Data_pin = 2; const int max_device = 4; bool stat = 0; #include "Out_74HC595.h" Out_74HC595 Out(Latch_pin, CLK_pin, Data_pin, max_device); #include "Cl_led.h" Cl_led led[] = { Cl_led(&Out, 0, 1, 0), // шина-Out,1 горит,1-я 74HC595,D0 Cl_led(&Out, 0, 1, 1), // шина-Out,1 горит,1-я 74HC595,D1 Cl_led(&Out, 0, 1, 2), // шина-Out,1 горит,1-я 74HC595,D2 Cl_led(&Out, 0, 1, 3) // шина-Out,1 горит,1-я 74HC595,D3 }; void setup() { Out.setup(); for (byte i = 0; i < 4; i++) led[i].setup(); led[0].blink(100); led[1].blink(150); led[2].blink(500); led[3].blink(1000); } void loop() { for (byte i = 0; i < 4; i++) led[i].loop(); }Вы хотите организовать на SPI ? Под шилд http://arduinolearning.com/code/multi-function-shield-examples.php
/*Seg_displ_A.ino каскад из 2х 74РС595N (POS - '0' SEG) Latch->4;(Latch_pin) ->10 CLK->7(CLK_pin) ->13 DI=8(DI_pin) ->11 */ //---------------------Cl_wire----------------------- #include <SPI.h> class Cl_wire { byte Latch_pin; byte max_device ; public: byte * buffer; Cl_wire(byte a, byte b): Latch_pin (a), max_device(b) { buffer = new byte[max_device]; } // setup setup() { SPI.begin(); pinMode(Latch_pin, OUTPUT); digitalWrite(Latch_pin, LOW); for (int j = max_device - 1; j >= 0; --j ) SPI.transfer(buffer[j] = 0x00); digitalWrite(Latch_pin, HIGH); } // запись void Write(byte adr, byte data) { buffer[adr] = data; digitalWrite(Latch_pin, LOW); for (int j = max_device - 1; j >= 0; --j ) SPI.transfer(buffer[j]); digitalWrite(Latch_pin, HIGH); } // запись 2-х байт void Write2byte(byte adr1, byte data1, byte adr2, byte data2) { buffer[adr1] = data1; buffer[adr2] = data2; digitalWrite(Latch_pin, LOW); for (int j = max_device - 1; j >= 0; --j ) SPI.transfer(buffer[j]); digitalWrite(Latch_pin, HIGH); } }; //------------------------Cl_74HC595H------------------- const byte Segment_font[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0X80, 0X90};//LOW const byte Pos_font[] = {0xF8, 0xF4, 0xF2, 0xF1}; // HIGH class Cl_74HC595H { Cl_wire *wire;//шина byte adr_p; // адрес ответ за позицию byte adr_s; // адрес ответ за цифру uint16_t data;// число на дисплее uint32_t past; byte i = 0; public: // конструктор Cl_74HC595H(Cl_wire *_wire, byte _adr_p, byte _adr_s): wire(_wire), adr_p(_adr_p), adr_s(_adr_s) {} void setup() { wire->Write2byte(adr_p, 0x00, adr_s, 0xFF); } void write(byte pos, byte data) { wire->Write2byte(adr_s, Segment_font[data], adr_p, Pos_font[pos]); } void write(uint16_t _data) { data = _data; } void loop() { write(0, data % 10); write(1, data / 10 % 10); write(2, data / 100 % 10); write(3, data / 1000 % 10); } }; //------------------------------------------------------------ Cl_wire wire(4, 20); //Cl_wire wire(4, 7, 8, 20); Cl_74HC595H Pos(&wire, 0, 1); void setup () { wire.setup(); Pos.setup(); Pos.write(1234); } void loop() { Pos.loop(); }От каскадного подключения регистров я отказался, мне показалось что проще будет выбирать нужный регистр и на него записывать данные, чем перезаписывать данные на всех регистрах. А по SPI как то проще, не надо в коде указывать к каким пинам что подключено(хотя я могу заблуждаться)
Указанный вами шилд не использую
Хорошо, сейчас займусь изучением. Спасибо!
Приветствую дорогие форумчане!
80 светодиодов, 8 сдвиговых регистров 74HC595, защелка каждого регистра подключена на отдельный выход ардуино, Arduino UNO .
8 сдвиговых регистров 74HC595 - это не 80, а 64 выхода.
Скорее вы заблуждаетесь. SPI "освобождает",точнее навязывает вам использовать CLK (13 прин) и MOSI() А дальше выбор микросхемы такой же.
10 регистров - 10 байт в памяти. Да хоть 100.
Меняете биты в этих байтах и выводите всё в регистры.
trembo - Вы правы я ошибся, конечно 64 светодиода.
10 регистров - 10 байт в памяти. Да хоть 100.
Меняете биты в этих байтах и выводите всё в регистры.
Так получается если я их подключаю каскадом, то код проще получается? Не нужно разбирать строку принятую из COM порта на номер регистра и число коорое нужно записать в регистр?
trembo - Вы правы я ошибся, конечно 64 светодиода.
И также вы ошибаетесь пытаясь параллельно выводить данные в последовательные регистры.
Помните чем закончилась эпоха PATA?
Правильно, появился SATA!
trembo - Вы правы я ошибся, конечно 64 светодиода.
И также вы ошибаетесь пытаясь параллельно выводить данные в последовательные регистры.
Помните чем закончилась эпоха PATA?
Правильно, появился SATA!
Просто я изначально решил выводить данные именно на тот регистр который мне нужен, а не на все сразу(изменяя данные на нужном регистре), думал что так проще, сейчас два пути
1 продолжать и написать функцию для разбора строки
2 переделать под последовательный вывод данных на регистры
пока не решил как поступить...
Например 0 выключить всё;
255 включить всё;
+45 включить LED №45;
-45 вЫключить LED №45;
Например 0 выключить всё;
255 включить всё;
+45 включить LED №45;
-45 вЫключить LED №45;
+45 Это если по одному включать.
А надо просто с компа передать столько байт сколько у вас регистров и всё
Где-то была готовая библиотека по приёму и выводу байтов на светодиоды.
Например 0 выключить всё;
255 включить всё;
+45 включить LED №45;
-45 вЫключить LED №45;
+45 Это если по одному включать.
А надо просто с компа передать столько байт сколько у вас регистров и всё
Где-то была готовая библиотека по приёму и выводу байтов на светодиоды.
8 регистров, 8-ми битное число, всего 64 байта(по байте на каждый выход) (это я больше для себя разжёвываю)
если вам не трудно скиньте пожалуйста ссылку на библиотеку
Нужно включать определенные светодиоды, не изменяя состояние других ранее включенных, это я попробую реализовать на каскадном подключении регистров, результат и код выложу, а пока пойду пробовать, всем спасибо за ответы и советы!
Не 64 байта, а 8 байт, 64 бита которые напрямую просто выводятся в регистр.
Не 64 байта, а 8 байт, 64 бита которые напрямую просто выводятся в регистр.
Глаза на лоб чуть не вылезли, конечно 8 байт, 64 бита, сам не понял как перепутал! 1 байт= 8 бит
Прошу прощения