Помогите допилить скетч
- Войдите на сайт для отправки комментариев
Втр, 12/04/2016 - 11:31
Сделал часы по проекту http://instructables.info/bolshie-nastennyie-chasyi-na-arduino/ вот скетч
#include <DS3232RTC.h>
#include <Time.h>
#include <Wire.h>
#include "FastLED.h"
#define NUM_LEDS 29 // Number of LED controles (remember I have 3 leds / controler
#define COLOR_ORDER BRG // Define color order for your strip
#define DATA_PIN 6 // Data pin for led comunication
CRGB leds[NUM_LEDS]; // Define LEDs strip
byte digits[10][7] = {{0,1,1,1,1,1,1}, // Digit 0
{0,1,0,0,0,0,1}, // Digit 1
{1,1,1,0,1,1,0}, // Digit 2
{1,1,1,0,0,1,1}, // Digit 3
{1,1,0,1,0,0,1}, // Digit 4
{1,0,1,1,0,1,1}, // Digit 5
{1,0,1,1,1,1,1}, // Digit 6
{0,1,1,0,0,0,1}, // Digit 7
{1,1,1,1,1,1,1}, // Digit 8
{1,1,1,1,0,1,1}}; // Digit 9 | 2D Array for numbers on 7 segment
bool Dot = true; //Dot state
bool DST = false; //DST state
int ledColor = 0x0000FF; // Color used (in hex)
void setup(){
// Serial.begin(9600);
// Wire.begin();
LEDS.addLeds<WS2811, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); // Set LED strip type
LEDS.setBrightness(255); // Set initial brightness
pinMode(2, INPUT_PULLUP); // Define DST adjust button pin
pinMode(4, INPUT_PULLUP); // Define Minutes adjust button pin
pinMode(5, INPUT_PULLUP); // Define Hours adjust button pin
}
// Get time in a single number, if hours will be a single digit then time will be displayed 155 instead of 0155
int GetTime(){
tmElements_t Now;
RTC.read(Now);
//time_t Now = RTC.Now();// Getting the current Time and storing it into a DateTime object
int hour=Now.Hour;
int minutes=Now.Minute;
int second =Now.Second;
if (second % 2==0) {Dot = false;}
else {Dot = true;};
return (hour*100+minutes);
};
// Check Light sensor and set brightness accordingly
void BrightnessCheck(){
const byte sensorPin = 3; // light sensor pin
const byte brightnessLow = 5; // Low brightness value
const byte brightnessHigh = 255; // High brightness value
int sensorValue = digitalRead(sensorPin); // Read sensor
if (sensorValue == 0) {LEDS.setBrightness(brightnessHigh);}
else {LEDS.setBrightness(brightnessLow);}
};
// Convert time to array needet for display
void TimeToArray(){
int Now = GetTime(); // Get time
int cursor = 29;
// Serial.print("Time is: ");Serial.println(Now);
if (DST){ // if DST is true then add one hour
Now+=100;
// Serial.print("DST is ON, time set to : ");Serial.println(Now);
};
if (Dot){leds[14]=ledColor;}
else {leds[14]=0x000000;
};
for(int i=1;i<=4;i++){
int digit = Now % 10; // get last digit in time
if (i==1){
// Serial.print("Digit 4 is : ");Serial.print(digit);Serial.print(" ");
cursor =22;
for(int k=0; k<=6;k++){
// Serial.print(digits[digit][k]);
if (digits[digit][k]== 1){leds[cursor]=ledColor;}
else if (digits[digit][k]==0){leds[cursor]=0x000000;};
cursor ++;
};
// Serial.println();
}
else if (i==2){
// Serial.print("Digit 3 is : ");Serial.print(digit);Serial.print(" ");
cursor -=14;
for(int k=0; k<=6;k++){
// Serial.print(digits[digit][k]);
if (digits[digit][k]== 1){leds[cursor]=ledColor;}
else if (digits[digit][k]==0){leds[cursor]=0x000000;};
cursor ++;
};
// Serial.println();
}
else if (i==3){
// Serial.print("Digit 2 is : ");Serial.print(digit);Serial.print(" ");
cursor =7;
for(int k=0; k<=6;k++){
// Serial.print(digits[digit][k]);
if (digits[digit][k]== 1){leds[cursor]=ledColor;}
else if (digits[digit][k]==0){leds[cursor]=0x000000;};
cursor ++;
};
// Serial.println();
}
else if (i==4){
// Serial.print("Digit1 is : ");Serial.print(digit);Serial.print(" ");
cursor =0;
for(int k=0; k<=6;k++){
// Serial.print(digits[digit][k]);
if (digits[digit][k]== 1){leds[cursor]=ledColor;}
else if (digits[digit][k]==0){leds[cursor]=0x000000;};
cursor ++;
};
// Serial.println();
}
Now /= 10;
};
};
void DSTcheck(){
int buttonDST = digitalRead(2);
// Serial.print("DST is: ");Serial.println(DST);
if (buttonDST == LOW){
if (DST){
DST=false;
// Serial.print("Switching DST to: ");Serial.println(DST);
}
else if (!DST){
DST=true;
// Serial.print("Switching DST to: ");Serial.println(DST);
};
delay(500);
};
}
void TimeAdjust(){
int buttonH = digitalRead(5);
int buttonM = digitalRead(4);
if (buttonH == LOW || buttonM == LOW){
delay(500);
tmElements_t Now;
RTC.read(Now);
int hour=Now.Hour;
int minutes=Now.Minute;
int second =Now.Second;
if (buttonH == LOW){
if (Now.Hour== 23){Now.Hour=0;}
else {Now.Hour += 1;};
}else {
if (Now.Minute== 59){Now.Minute=0;}
else {Now.Minute += 1;};
};
RTC.write(Now);
}
}
void loop() // Main loop
{
BrightnessCheck(); // Check brightness
DSTcheck(); // Check DST
TimeAdjust(); // Check to se if time is geting modified
TimeToArray(); // Get leds array with required configuration
FastLED.show(); // Display leds array
}
но есть следующие проблемы: не хочет работать датчик освещенности (Если крутнуть на нем потинцометр то светят или ярко или тускло как для ночного режима, но автоматом не реагирует), если отключить питание, а потом вновь подать, минуты продолжают идти как и положено, а вот часы на час сдвигаются. И самое интересное для чего третья кнопка? Одна часы, вторая минуты, а что такое третье (DST)? DO лайт сенсора на D3 ардуинки, часы SCL на A5, SDA на A4 (ну питание само собой)
dj-toxa,
начнём с того, что скетч ужасен. Он безграмотен и просто как программа и по использованию замечательной микросхемы 3232 - тут ею разве что гвозди не забивают.
Ну, вот, посмотрите, ну кто ж так пишет (стр. 121-128)
if (DST) { DST = false; // Serial.print("Switching DST to: ");Serial.println(DST); } else if (!DST) { DST = true; // Serial.print("Switching DST to: ");Serial.println(DST); };Вам не кажется, что этот бред эквивалентен одной единственной вот такой строке?
ну, и много где подобного - код ужасен.
Далее, теперь об использовании микросхемы. У этих часов есть ещё один пин SQW на коорый они могут выдавать прерывание каждую минуту или каждую секунду - как настроите. Причём, точно при переходе минуты/секунды. Так вот обновлять часы нужно не когда попало (как в этом скетче) а именно по этому прерыванию. Тогда часы будут обновляться точно на переходе минуты/секунды. А так как здесь, может минута давно перешла, а они у Вас обновятся когда "очередь дойдёт".
По поводу Вашего вопроса про освещённость.
У автора, наверняка, была ещё какая-то приблуда на датчике освещённости типа триггера Шмитта. Он включает повышенную яркость, когда татчик возвращает 0 (строки 51-52). У Вас же датчик наверняка не 0 возвращает. Поставьте печать значения sensorValue после строки 50 и посмотрите что он возвращает при разных освещениях и тогда переделайте строки 51-52 как Вам надо.
А вообще, мой совет - скетч в мусорную корзину и писать свой, по-человечески.
Евгений спасибо за ответ, сильно не пинайте Ардуино только начию курить. Скетч писал автор статьи и как я понял он тоже не особо в этом разбирается. По поводу датчика освещения Вас понял попробую завтра поиграться с 51й строкой погляжу что выйдет. А по поводу DST не понял и что это вообще такое? (переход на летнее время) И по поводу данного скетча, все ли я нужные библиотеки добавил DS3232RTC.h, Time.h, FastLED.h. Wire.h отдельно существует или она содержится в одном из перечисленных?
Wire живёт отдельно, она у Вас есть - вместе с Ардуино средой идёт.
DST - да, переход на летнее время.
А пин SQW у модуля часов нашли?
SQW то на плате видел, но вот что с ним делать и куда его лепить не понятно =)
то есть мои часы после отключения и включения питания убегают на час из за того что bool DST = false; //DST state (DST-выключен)
SQW то на плате видел, но вот что с ним делать и куда его лепить не понятно =)
Я Вам писал в прощлом посте.
Вообще с этим пином можно делать следующее
1) назначить будильник на конкретное время или на каждый день или на кажду неделю, год и т.п. Тогда по наступлению этого времени на этот пин будет валиться прерывание. Кстати, в микросхеме два свтроенных будильника, каждый из которых можно независимо настраивать.
2. Назначить. чтобы от падал в LOW каждую секунду или каждую минуту. Об этом я Вам писал раньше. Это даёт Вам возможность обновлять время на экране точно в момент перехода минуты/секунды
Когда наступает прерывание, пин SQW падает в LOW. Поэтому, чтобы всё это работало, надо не только назначить всё как надо, но и соединить SQW с пином 2 или 3 ардуины. Тогда в скетче Вы можете назначить на этот пин attachInterrupt и снимать с него прерывание по FALLING.
то есть мои часы после отключения и включения питания убегают на час из за того что bool DST = false; //DST state (DST-выключен)
Не знаю, смотреть надо. Печатать в сериал отладочную информацию и смотреть. Этот скетч настолько перегружен ненужностями, что ....
Поэксперементировал сегодня датчиком освещения результата ноль =( Но продолжив эксперементы вставил в скетч код для красивой смены цвета часов после каждого окончания минуты (и тут случилось странное) часы перестали убегать на час после отключения питания =) ни че не понимаю. Вообщем пока висит вопрос по датчику освещенности. Вот новый скетч (еще убрать бы все лишнее из него)
#include <DS3231RTC.h> #include <Time.h> #include <Wire.h> #include "FastLED.h" #define NUM_LEDS 29 // Number of LED controles (remember I have 3 leds / controler #define COLOR_ORDER BRG // Define color order for your strip #define DATA_PIN 6 // Data pin for led comunication CRGB leds[NUM_LEDS]; // Define LEDs strip byte digits[10][7] = {{0,1,1,1,1,1,1}, // Digit 0 {0,1,0,0,0,0,1}, // Digit 1 {1,1,1,0,1,1,0}, // Digit 2 {1,1,1,0,0,1,1}, // Digit 3 {1,1,0,1,0,0,1}, // Digit 4 {1,0,1,1,0,1,1}, // Digit 5 {1,0,1,1,1,1,1}, // Digit 6 {0,1,1,0,0,0,1}, // Digit 7 {1,1,1,1,1,1,1}, // Digit 8 {1,1,1,1,0,1,1}}; // Digit 9 | 2D Array for numbers on 7 segment bool Dot = true; //Dot state bool DST = false; //DST state int last_digit = 0;//long ledColor = CRGB::DarkOrchid; // Color used (in hex) long ledColor = CRGB::MediumVioletRed; long ColorTable[16] = { CRGB::Amethyst, CRGB::Aqua, CRGB::Blue, CRGB::Chartreuse, CRGB::DarkGreen, CRGB::DarkMagenta, CRGB::DarkOrange, CRGB::DeepPink, CRGB::Fuchsia, CRGB::Gold, CRGB::GreenYellow, CRGB::LightCoral, CRGB::Tomato, CRGB::Salmon, CRGB::Red, CRGB::Orchid}; void setup(){ // Serial.begin(9600); // Wire.begin(); LEDS.addLeds<WS2811, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); // Set LED strip type LEDS.setBrightness(255); // Set initial brightness pinMode(2, INPUT_PULLUP); // Define DST adjust button pin pinMode(4, INPUT_PULLUP); // Define Minutes adjust button pin pinMode(5, INPUT_PULLUP); // Define Hours adjust button pin } // Get time in a single number, if hours will be a single digit then time will be displayed 155 instead of 0155 int GetTime(){ tmElements_t Now; RTC.read(Now); //time_t Now = RTC.Now();// Getting the current Time and storing it into a DateTime object int hour=Now.Hour; int minutes=Now.Minute; int second =Now.Second; if (second % 2==0) {Dot = false;} else {Dot = true;}; return (hour*100+minutes); }; // Check Light sensor and set brightness accordingly void BrightnessCheck(){ const byte sensorPin = 3; // light sensor pin const byte brightnessLow = 5; // Low brightness value const byte brightnessHigh = 255; // High brightness value int sensorValue = digitalRead(sensorPin); // Read sensor if (sensorValue == 0) {LEDS.setBrightness(brightnessHigh);} else {LEDS.setBrightness(brightnessLow);} }; // Convert time to array needet for display void TimeToArray(){ int Now = GetTime(); // Get time int cursor = 29; // Serial.print("Time is: ");Serial.println(Now); if (DST){ // if DST is true then add one hour Now+=100; // Serial.print("DST is ON, time set to : ");Serial.println(Now); }; if (Dot){leds[14]=ledColor;} else {leds[14]=0x000000; }; for(int i=1;i<=4;i++){ int digit = Now % 10; // get last digit in time if (i==1){ // Serial.print("Digit 4 is : ");Serial.print(digit);Serial.print(" "); cursor =22; for(int k=0; k<=6;k++){ // Serial.print(digits[digit][k]); if (digits[digit][k]== 1){leds[cursor]=ledColor;} else if (digits[digit][k]==0){leds[cursor]=0x000000;}; cursor ++; }; Serial.println(); if (digit != last_digit) { fadefonction(); ledColor = ColorTable[random(16)]; } last_digit = digit; }// fin if else if (i==2){ // Serial.print("Digit 3 is : ");Serial.print(digit);Serial.print(" "); cursor -=14; for(int k=0; k<=6;k++){ // Serial.print(digits[digit][k]); if (digits[digit][k]== 1){leds[cursor]=ledColor;} else if (digits[digit][k]==0){leds[cursor]=0x000000;}; cursor ++; }; // Serial.println(); } else if (i==3){ // Serial.print("Digit 2 is : ");Serial.print(digit);Serial.print(" "); cursor =7; for(int k=0; k<=6;k++){ // Serial.print(digits[digit][k]); if (digits[digit][k]== 1){leds[cursor]=ledColor;} else if (digits[digit][k]==0){leds[cursor]=0x000000;}; cursor ++; }; // Serial.println(); } else if (i==4){ // Serial.print("Digit1 is : ");Serial.print(digit);Serial.print(" "); cursor =0; for(int k=0; k<=6;k++){ // Serial.print(digits[digit][k]); if (digits[digit][k]== 1){leds[cursor]=ledColor;} else if (digits[digit][k]==0){leds[cursor]=0x000000;}; cursor ++; }; // Serial.println(); } Now /= 10; }; }; void DSTcheck(){ int buttonDST = digitalRead(2); // Serial.print("DST is: ");Serial.println(DST); if (buttonDST == LOW){ if (DST){ DST=false; // Serial.print("Switching DST to: ");Serial.println(DST); } else if (!DST){ DST=true; // Serial.print("Switching DST to: ");Serial.println(DST); }; delay(500); }; } void TimeAdjust(){ int buttonH = digitalRead(5); int buttonM = digitalRead(4); if (buttonH == LOW || buttonM == LOW){ delay(500); tmElements_t Now; RTC.read(Now); int hour=Now.Hour; int minutes=Now.Minute; int second =Now.Second; if (buttonH == LOW){ if (Now.Hour== 23){Now.Hour=0;} else {Now.Hour += 1;}; }else { if (Now.Minute== 59){Now.Minute=0;} else {Now.Minute += 1;}; }; RTC.write(Now); } } void fadeall() { for(int m = 0; m < NUM_LEDS; m++) { leds[m].nscale8(250); } } void fadefonction () { static uint8_t hue = 0; // First slide the led in one direction for(int i = 0; i < NUM_LEDS; i++) { // Set the i'th led to red leds[i] = CHSV(hue++, 255, 255); // Show the leds FastLED.show(); // now that we've shown the leds, reset the i'th led to black // leds[i] = CRGB::Black; fadeall(); // Wait a little bit before we loop around and do it again delay(10); } // Now go in the other direction. for(int i = (NUM_LEDS)-1; i >= 0; i--) { // Set the i'th led to red leds[i] = CHSV(hue++, 255, 255); // Show the leds FastLED.show(); // now that we've shown the leds, reset the i'th led to black // leds[i] = CRGB::Black; fadeall(); // Wait a little bit before we loop around and do it again delay(10); } } void loop() // Main loop { BrightnessCheck(); // Check brightness DSTcheck(); // Check DST TimeAdjust(); // Check to se if time is geting modified TimeToArray(); // Get leds array with required configuration FastLED.show(); // Display leds array }long ledColor = CRGB::MediumVioletRed; 024 long ColorTable[16] = { 025 CRGB::Amethyst, 026 CRGB::Aqua, 027 CRGB::Blue, 028 CRGB::Chartreuse, 029 CRGB::DarkGreen, 030 CRGB::DarkMagenta, 031 CRGB::DarkOrange, 032 CRGB::DeepPink, 033 CRGB::Fuchsia, 034 CRGB::Gold, 035 CRGB::GreenYellow, 036 CRGB::LightCoral, 037 CRGB::Tomato, 038 CRGB::Salmon, 039 CRGB::Red, 040 CRGB::Orchid};Сюда я понимаю можно добать сколько угодно цветов? А почему тут они указываются не в (HEX) как в
intledColor = 0x0000FF;// Color used (in hex)Поэксперементировал сегодня датчиком освещения результата ноль =(
Что значит 0?
Я же Вас просил "Поставьте печать значения sensorValue после строки 50 и посмотрите что он возвращает при разных освещениях и тогда переделайте строки 51-52 как Вам надо". Ну и расскажите, что печатает-то. Жалетельно копи-пасту из монитора порта.
Эксперементировал меняя в коде значение
if(sensorValue == 0), а вот что в мониторе порта писать для опроса я просто не знаю ))И я думал ардуинку к компу можно только одну подключать без модулей, а раз так от чего запитывать модуль? Был неудачный опыт подключения запитаной от БП 5В ардуинки (27 лапа и минус) к компу и она испустив дым померла. Хотя читал где то что ардуинка вроде как сама выбирает налучий источник питания.Эксперементировал меняя в коде значение
if(sensorValue == 0), а вот что в мониторе порта писать для опроса я просто не знаю ))После строки:
Вставьте, например:
Serial.print("SensorValue = "); Serial.println(sensorValue);И я думал ардуинку к компу можно только одну подключать без модулей, а раз так от чего запитывать модуль? Был неудачный опыт подключения запитаной от БП 5В ардуинки (27 лапа и минус) к компу и она испустив дым померла. Хотя читал где то что ардуинка вроде как сама выбирает налучий источник питания.
Модуль запитать от ардуинки (вывод 5V), не вариант?
Внешнее питание нужно заводить на вывод VIN.
Эксперементировал меняя в коде значение
if(sensorValue == 0), а вот что в мониторе порта писать для опроса я просто не знаю ))И я думал ардуинку к компу можно только одну подключать без модулей, а раз так от чего запитывать модуль? Был неудачный опыт подключения запитаной от БП 5В ардуинки (27 лапа и минус) к компу и она испустив дым померла. Хотя читал где то что ардуинка вроде как сама выбирает налучий источник питания.Вы не поняли. Просто для отладки после строки 50 поставьте
Serial.print("SV=");
Serial.println(SensorValue);
Сегодня потестил как оказалось вся проблемя была в датчике,а не в коде. Тестил в пасмурную погоду с люминистентным освещением, даже если подстроечным потенцометром выставить на максимальную чувствительность срабатывает только при навидении (диода) на окно либо на включеную дополнитенльно настольную лампу с лампой накаливания. В логе монитора порта в зависимости от условия либо SensorValue=0, либо SensorValue=1. Тоесть либо светло либо нет. Как бы чувствительности добавить? И почему интересно он свет от ламп дневного света за свет не считает =) (включается срого при наведении на окно,чуть влево,чуть вправо все для него ночь =))
Ну, вот, давно бы так. Я ж Вам давно говорил - напечатайте. И имейте в виду - это общий принцип - не работайте вслепую! Смотрите что и где у Вас получается.
И почему интересно он свет от ламп дневного света за свет не считает =)
У датчиков есть дины волн, которые они видят, а другие волны они не видят
Как бы чувствительности добавить?
Взять другой датчик.
У автора такой же датчик на LM393, но в качестве фотоэлемента у него фоторезистор, а у меня фотодиод. Как всегда китаёзы удешевляют производство, ставя более дешманские детали =) На датчике есть кроме цифрового и аналоговый выход, может на аналоге чувствительность лучше будет? И куда его посадить, читал что вроде садят на А4 или А5, но у меня на них DS3231RTC, на другой аналоговый можно?
садят на А4 или А5, но у меня на них DS3231RTC, на другой аналоговый можно?
Ну, если он один (просто аналоговый выход), то можно на любой. Попробуйте.
Только опять совет из той же серии - не работайте вслепую.
Поставьте и запустите простейший скетч из двух строк: читаете analogRead'ом и печатаете в сериал. Посмотрите, что выдаётся и только потом пытайтесь вставить в основной скетч уже зная, что там валится.
А то в большом скетче никогда не понятно что именно не работает.