Форум по Роботика
Контролери => Ардуино (Arduino) => Темата е започната от: killara1 в Април 21, 2013, 07:55:38 pm
-
Имам няколко въпроса.Как да направя така че:
Ардуиното да ми записва информация но в себе си.Няколко променливи.
Ще започна по от далеч, от няколко дни започнах да си правя един инкубатор( :-D ). И си направих всичко необходимо от механична час, лампи, моторчета и т.н., но започвайки да пиша кода за ардуино, имам проблем.Идеята ми е да си записва сам време в променливи(секидна,минута,час,ден) , и на всеки час да прави оборот на моторчето, на ден 3-ти да пуска само вентилатор за около 10-15 секунди. На ден 6-ти 15-20, и т.н. , но в същото време да си следи температурата с един термистор и ако температурата падне да подава ток на лампичката да загрее самия инкубатор, чрез едни транзистор. Но решавайки да проверя до сега кода, зареждам кода на ардуйното, пускам серийната комуникация и ми показва само едни и съши цифри, което не ми върши работа. ето част от кода int motor1A = 1;
int motor1B = 2;
int motor1C = 3;
byte sekund=35;
byte minet=0;
byte hour=3;
byte hour2=1;
byte day=0;
byte rootingDerection=0;
int val;
void setup() {
pinMode(motor1A, OUTPUT);
pinMode(motor1B, OUTPUT);
pinMode(motor1C, OUTPUT);
Serial.begin(9600);
}
void loop() {
if (hour>hour2){analogWrite(motor1C, 120);
digitalWrite(motor1A, HIGH);
digitalWrite(motor1B, LOW);
delay(200);
val=hour2+hour;
hour2=val;
sekund=sekund+2;
}
Serial.println(sekund);
Serial.println(val);
delay(200);
}
Променливата "hour2" , е за проверка на сегашния час.
-
Използвай командите за четене и запис във вградения ЕЕПРОМ на ATmega:
Първо включваш файла за работа с EEPROM:
#include <EEPROM.h>
Синтаксис на запис в EEPROM:
EEPROM.write(addr, val);
Записва на адрес addr стойността на променлива val.
Пример: EEPROM.write(0, 56); //Ще запише на адрес 0 стойност 56.
Синтаксис на четене от EEPROM:
EEPROM.read(addr);
Пример: val = EEPROM.read(0);
Ще присвои на променлива val съдържанието на адрес 0
Ако следваме логиката на горния пример, на val ще се присвои стойност 56.
Адресите започват от 0 и завършват, съгласно спецификацията на конкретния контролер.
-
Много благодаря, за бързия отговор. Ще погледна и информацията в сайта им.
След оглед на нещата, забелязвам че имам право на само 100,000 презаписвания което е малко некомфортно. Някакви други идеи.
-
Другият вариант е външна EEPROM. 100,000 не е толкова малко. Но външната памет има безспорни предимства - слагаш я на цокъл. Като направи проблем, мяташ в кофата и следващата.
Аз лично прилагам няколко трика при работа с външна EEPROM:
1. Въвеждам контролна стойност на някакъв адрес в EEPROM. Да кажем - на адрес 255, записвам стойност 63.
2. Ако работя с LCD, първо инициализирам LCD-то и EEPROM. След което изписвам съобщение "Грешка EEPROM" и веднага искам да прочета адрес 255.
3. Следващата команда е изписване на друг текст на LCD.
4. Ако адресът се прочете успешно, "Грешка EEPROM" се сменя толкова бързо от следващото съобщение, че потребителят не го вижда. Ако има "увисване" при четенето, на дисплея остава съобщение за грешка в паметта.
5. Ако контролната стойност на адрес 255 е 0xFF, значи паметта не е записвана(нова е) и следва извикване на подпрограма за въвеждане на стойности по подразбиране. В общия случай създавам дъмп със стойности по подразбиране в програмната памет, който копирам в EEPROM(например масив от 255 елемента). Ако контролната стойност е очакваната - 63, директно се изълнява главната програма - значи, че паметта е инициализирана.
-
А някаква идея с flash памет нямали да стане?
-
Ами не знам как ще се справиш с флаш паметта...
Най-лесно е с EEPROM - I2C комуникация и готово.
24C02: 1,000,000 цикъла и 40 години помни...
По каква причина искаш да ползваш флаш памет?
-
Ми мисля че флаша ще издържи повече. Но ще го направя с ЕЕПРОМ
-
1,000,000 записвания е огромен брой! При 24 записа дневно, ще ти стигнат някъде за около 114 години. След това ще си купиш друг EEPROM :D
Дефинирай и алгоритмизирай заданието, за да започнем да се занимаваме с кода.
PS: Променливата за минути можеш да запишеш като minutes, че тук сме основно българоговорящи и паднах от смях, като прочетох какво име си й дал :clap: (не се сърди, шегувам се) :) .
-
Знам в бързането не съм я написъл правилно. По късно ще напиша кода.
-
Това успях да сътворя
int motor1A = 1;
int motor1B = 2;
int motor1C = 3;
byte sekund=0;
byte minutes=0;
byte hour=0;
byte hour2=0;
byte day=0;
byte rootingDerection=0;
int sensePinT=0;
int lampPin=4;
int fanPin=7;
int errorLedPin=8;
void setup() {
pinMode(motor1A, OUTPUT);
pinMode(motor1B, OUTPUT);
pinMode(motor1C, OUTPUT);
pinMode(lampPin, OUTPUT);
pinMode(fanPin, OUTPUT);
pinMode(errorLedPin,OUTPUT);
}
void loop() {
if (day==21&&hour==12){
// тук трабва да се презапишат всички промнливи на 0.
}
if (sekund>59) {
sekund=0;
minutes=minutes+1;}
if(minutes>59){
minutes=0;
hour=hour+1;}
if(hour>24){hour=0;
day=day+1;
if (rootingDerection==0){
analogWrite(motor1C, 120);
digitalWrite(motor1A, HIGH);
digitalWrite(motor1B, LOW);
delay(200);
analogWrite(motor1C, 0);
digitalWrite(motor1A, LOW);
digitalWrite(motor1B, LOW);
delay(200);
rootingDerection=1;
}
else if (rootingDerection==1){
analogWrite(motor1C, 120);
digitalWrite(motor1A, HIGH);
digitalWrite(motor1B, LOW);
delay(200);
analogWrite(motor1C, 0);
digitalWrite(motor1A, LOW);
digitalWrite(motor1B, LOW);
delay(200);
rootingDerection==0;
}
else{digitalWrite(errorLedPin,HIGH);}
hour2=hour2+hour;
sekund=sekund+2;
}
if (hour>hour2){
if (rootingDerection==0){
analogWrite(motor1C, 120);
digitalWrite(motor1A, HIGH);
digitalWrite(motor1B, LOW);
delay(200);
analogWrite(motor1C, 0);
digitalWrite(motor1A, LOW);
digitalWrite(motor1B, LOW);
delay(200);
rootingDerection=1;
}
else if (rootingDerection==1){
analogWrite(motor1C, 120);
digitalWrite(motor1A, HIGH);
digitalWrite(motor1B, LOW);
delay(200);
analogWrite(motor1C, 0);
digitalWrite(motor1A, LOW);
digitalWrite(motor1B, LOW);
delay(200);
rootingDerection==0;
}
else{digitalWrite(errorLedPin,HIGH);}
hour2=hour2+hour;
sekund=sekund+2;
}
else{digitalWrite(errorLedPin,HIGH);}
int val=analogRead(sensePinT);
if (val<530) {
digitalWrite(lampPin,HIGH);
digitalWrite(fanPin,LOW);}
else if (val>650){
digitalWrite(lampPin,LOW);
digitalWrite(fanPin,HIGH);}
else{digitalWrite(errorLedPin,HIGH);}
delay(200);
sekund+1;
// И предполагам че тук трабва да се презапишат всички изпозвани променливи в EEPROM.
}
Сега си спомням че някъде четох за една функция която давала точно преди колко време е била включено ардуино платката, не знам да ли няма да ми свърши работа.
-
Като начало:
hour=hour=1
-
Благодаря поправих го.
-
Не съм се задълбочавал в кода, но не видях къде отброяваш време 1 секунда, за да увеличиш брояч секунди. Ако ползваш Delay, имай предвид, че операциите по обработка добавят време и импулсите ще са неточни, т.е. ще имаш натрупване на грешка.Желателно е да ползваш прекъсване от таймер.
-
Смисъл от какъв таймер.
-
Вграден таймер на ATMega. Прочети например:
http://www.instructables.com/id/Arduino-Timer-Interrupts/
Това пък е от страницата на Ардуино:
http://playground.arduino.cc/code/timer1
-
До тук добре, разбрах малко, но може ли да ми покажеш как да си свормирам кода.
-
Някой.
-
Формулирай точно алгоритъма и ще го направим. За да не се налага да се извлича алгоритъм от частично написан код. Така се увеличава шансът за грешка в новия алгоритъм.
-
Ето една програма направена за две минути-copy/paste от примера BlinkWithoutDelay!!!
#include <LiquidCrystal.h>
int sekund =0;
int minutes =0;
int hour =0;
int hour2 =0;
int day =0;
long previousMillis = 0;
long interval = 999;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
lcd.begin(20, 4);
lcd.setCursor(0, 0);
lcd.print("Timer");
lcd.setCursor(0, 1);
lcd.print("Day:");
}
void loop()
{
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
sekund = sekund++;
if (sekund>59) {
sekund=0;
minutes=minutes+1;
}
if(minutes>59){
minutes=0;
hour=hour+1;
}
if(hour>24)
{
hour=0;
day=day+1;
}
if(sekund <= 9){
lcd.setCursor(6, 2);
lcd.print("0");
lcd.setCursor(7, 2);
lcd.print(sekund);
}else{
lcd.setCursor(6, 2);
lcd.print(sekund);
}
if(minutes <= 9){
lcd.setCursor(3, 2);
lcd.print("0");
lcd.setCursor(4, 2);
lcd.print(minutes);
}else{
lcd.setCursor(3, 2);
lcd.print(minutes);
}
if(hour <= 9){
lcd.setCursor(0, 2);
lcd.print("0");
lcd.setCursor(1, 2);
lcd.print(hour);
}else{
lcd.setCursor(0, 2);
lcd.print(hour);
}
lcd.setCursor(4, 1);
lcd.print(day);
lcd.setCursor(2, 2);
lcd.print(":");
lcd.setCursor(5, 2);
lcd.print(":");
}
}
Имай едно на ум, че процесора губи време да опреснява LCD и затова в моят случай long interval е 999ms!!!
И въпреки това пак ще има минимална грешка, няма да е швейцарски часовник, но все пак пилетата не се излюпват на 21-я ден в точно определен час, минута и секунда.......