Придумываю новый приборчик :-)
Jun. 8th, 2014 12:00 amНа Arduine делаю со студентами квалификационную работу.
Центральный модуль, маленький индикатор, 8 каналов измерений, пара каналов телемеханики, вывод информации на компутер и приём команд с компутера. Измеряет параметры, логирует на общей временной шкале. В зависимости от заданных параметров измеряемых сигналов может выполнять действия.
Масштабируемость до разумных пределов. Модульность. Можно добавить модуль Wi-Fi, GPS, GSM и т.д.
Сейчас набросал чтение кнопок и индикацию активных каналов. Мне кажется красиво получилось :-))
Уже переключает каналы измерения, выводит информацию на комп и на собственный индикатор. Так как датчик у меня пока всего один, то во все каналы выводит одну и ту же информацию - температуру.
#include <OneWire.h> // Библиотека шины передачи данных. Сайт - http://www.pjrc.com/teensy/td_libs_OneWire.html
#include <TM1638.h> // Библиотека индикатора LKM-1638 адрес сайта - http://code.google.com/p/tm1638-library/
TM1638 module(8, 9, 7, true, 0); // Подключение одного модуля индикатора - Pin 8 - 4 (DIO), Pin 9 - 3 (CLK), Pin 7 - 5 (STB0).
OneWire ds(10); // on pin 10 (a 4.7K resistor is necessary)
boolean button [] = { LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW }; // Устанавливаем начальное значение кнопок.
float celsius; // Значение температуры (канал 1).
byte chanal; // Указатель канала измерений.
void setup() { // Первоначальная инициализация контроллера.
TestSegment(); // Проверка исправности индикатора.
SetInput(); // Приглашение в режим выбора каналов.
Serial.begin(9600); // открывает последовательный порт, устанавливает скорость 9600 бит.
}
void loop() {
ReadButton();
for (byte i = 0; i < 8; i++) {
if (button[i] == HIGH ){
Temperature();
chanal = i+1;
Send_to_PC();
Send_to_LCD();
}
else if ( button[0]==0&&button[1]==0&&button[2]==0&&button[3]==0&&button[4]==0&&button[5]==0&&button[6]==0&&button[7]==0 ) {
SetInput();
} }
}
//----------------------------------------------------------------------------------------------------------------------------------------
void TestSegment () { // Функция "Проверка индикатора".
for (int i = 1; i < 256; i=i*2){
byte segment[] = { i,i,i,i,i,i,i,i }; // перебираем все значения по очереди.
module.setDisplay(segment); // Высвечивает на индикаторе отдельные сегменты.
delay(300); // Задержка 0,3 секунды.
}
byte segment[] = { 255, 255, 255, 255, 255, 255, 255, 255 }; // 255 - включает все сегменты.
module.setDisplay(segment); // Зажигаем все сегменты индикатора.
delay(500); // Задержка 0,5 секунды.
module.clearDisplay(); // Очистка экрана.
}
//----------------------------------------------------------------------------------------------------------------------------------------
void SetInput() { // Функция - "приглашение к работе".
String Text = "SetInput"; // Текст приглашения.
module.setDisplayToString(Text); // Вывод строки текста на дисплей.
}
//----------------------------------------------------------------------------------------------------------------------------------------
void ReadButton (){ // Функция считывания нажатия кнопок и индикация нажатых кнопок.
byte avalibleButton[] = { 1, 2, 4, 8, 16, 32, 64, 128 }; // Перечисляем все возможные варианты нажатия кнопок (например, кн.1 + кн.7 = 65)
int key = module.getButtons(); // Считываем значение нажатой кнопки.
for ( int i = 0; i < 8; i++ ) {
if ( avalibleButton[i] == key ) {
button[i] = !button[i];
module.setLED(2*button[i], i);
delay(500);
}}
}
//----------------------------------------------------------------------------------------------------------------------------------------
void Temperature() {
byte data[12];
byte addr[8];
ds.search(addr);
ds.reset();
ds.select(addr);
ds.write(0x44, 1); // start conversion, with parasite power on at the end
delay(800); // maybe 750ms is enough, maybe not. We might do a ds.depower() here, but the reset will take care of it.
ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
for ( byte i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
}
int16_t raw = (data[1] << 8) | data[0];
raw = raw << 3; // 9 bit resolution default
raw = (raw & 0xFFF0) + 12 - data[6];
celsius = (float)raw / 16.0;
}
//----------------------------------------------------------------------------------------------------------------------------------------
void Send_to_PC(){
Serial.print("Chanal measurements - ");
Serial.print(chanal,DEC);
Serial.print(" Temperature = ");
Serial.print(celsius);
Serial.print(" Celsius, ");
Serial.print("time - ");
Serial.print(millis()/1000);
Serial.println("");
}
//----------------------------------------------------------------------------------------------------------------------------------------
void Send_to_LCD() {
//module.clearDisplay();
module.setDisplayToDecNumber(celsius*100, 4, false);
module.setDisplayDigit(chanal, 0, true);
}
Первые проблемки. Ожидаемые и не очень.
Date: 2014-06-08 10:53 am (UTC)Теперь приходится удерживать нажатой кнопку по 10 секунд, прежде чем включится светодиод.
Это из-за оператора delay() в цикле измерения температуры.
Допустим, мы не будем измерять температуру 2-3 раза в секунду, температура - параметр инертный, можно раз в 5 секунд проверять.
Но ведь измерение напряжения, например, надо производить с максимальной частотой.
Re: Первые проблемки. Ожидаемые и не очень.
Date: 2014-06-08 10:46 pm (UTC)-----------
float Temperature() {
byte data[12];
byte addr[8];
if (Flag == LOW) {
ds.search(addr);
ds.reset();
ds.select(addr);
ds.write(0x44, 1); // start conversion, with parasite power on at the end
oldmillis = millis();
Flag = HIGH;
}
if ((millis() - oldmillis) > 1000 ) {
ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
for ( byte j = 0; j < 9; j++) { // we need 9 bytes
data[j] = ds.read();
}
int16_t raw = (data[1] << 8) | data[0];
raw = raw << 3; // 9 bit resolution default
raw = (raw & 0xFFF0) + 12 - data[6];
celsius = (float)raw / 16.0;
Flag = LOW;
}
return celsius;
}
-----------------------
теперь все кнопки обрабатываются быстро, без задержки. Да и другим функциям не будет тормозить.
Re: Первые проблемки. Ожидаемые и не очень.
Date: 2014-06-09 11:22 am (UTC)Иначе не получается изменять время опроса датчика температуры.
Если он требуется, например, раз в минуту, то проходит слишком много времени и теряются данные на шине датчика. Там нужно именно одну секунду ждать.
Ладно, применю идею в другом месте :-)