Форум по Роботика

Контролери => Ардуино (Arduino) => Темата е започната от: killara1 в Април 21, 2013, 07:55:38 pm

Титла: 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" , е за проверка на сегашния час.
Титла: Arduino код?
Публикувано от: emil74 в Април 22, 2013, 09:54:13 am
Използвай командите за четене и запис във вградения ЕЕПРОМ на 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 и завършват, съгласно спецификацията на конкретния контролер.
Титла: Arduino код?
Публикувано от: killara1 в Април 22, 2013, 11:38:24 am
Много благодаря, за бързия отговор. Ще погледна и информацията в сайта им.
След оглед на нещата, забелязвам че имам право на само 100,000 презаписвания което е малко некомфортно. Някакви други идеи.
Титла: Arduino код?
Публикувано от: emil74 в Април 22, 2013, 02:18:19 pm
Другият вариант е външна EEPROM. 100,000 не е толкова малко. Но външната памет има безспорни предимства - слагаш я на цокъл. Като направи проблем, мяташ в кофата и следващата.
  Аз лично прилагам няколко трика при работа с външна EEPROM:
  1. Въвеждам контролна стойност на някакъв адрес в EEPROM. Да кажем - на адрес 255, записвам стойност 63.  
  2. Ако работя с LCD, първо инициализирам LCD-то и EEPROM. След което изписвам съобщение "Грешка EEPROM" и веднага искам да прочета адрес 255.
  3. Следващата команда е изписване на друг текст на LCD.
  4. Ако адресът се прочете успешно, "Грешка EEPROM" се сменя толкова бързо от следващото съобщение, че потребителят не го вижда. Ако има "увисване" при четенето, на дисплея остава съобщение за грешка в паметта.
  5. Ако контролната стойност на адрес 255 е 0xFF, значи паметта не е записвана(нова е) и следва извикване на подпрограма за въвеждане на стойности по подразбиране. В общия случай създавам дъмп със стойности по подразбиране в програмната памет, който копирам в EEPROM(например масив от 255 елемента). Ако контролната стойност е очакваната - 63, директно се изълнява главната програма - значи, че паметта е инициализирана.
Титла: Arduino код?
Публикувано от: killara1 в Април 22, 2013, 07:22:51 pm
А някаква идея с flash памет нямали да стане?
Титла: Arduino код?
Публикувано от: emil74 в Април 22, 2013, 10:10:34 pm
Ами не знам как ще се справиш с флаш паметта...
Най-лесно е с EEPROM - I2C комуникация и готово.
24C02: 1,000,000 цикъла и 40 години помни...
По каква причина искаш да ползваш флаш памет?
Титла: Arduino код?
Публикувано от: killara1 в Април 23, 2013, 05:55:03 am
Ми мисля че флаша ще издържи повече. Но ще го направя  с ЕЕПРОМ
Титла: Arduino код?
Публикувано от: emil74 в Април 23, 2013, 08:04:18 am
1,000,000 записвания е огромен брой! При 24 записа дневно, ще ти стигнат някъде за около 114 години. След това ще си купиш друг EEPROM :D

Дефинирай и алгоритмизирай заданието, за да започнем да се занимаваме с кода.

PS: Променливата за минути можеш да запишеш като minutes, че тук сме основно българоговорящи и паднах от смях, като прочетох какво име си й дал  :clap: (не се сърди, шегувам се)  :) .
Титла: Arduino код?
Публикувано от: killara1 в Април 23, 2013, 08:23:33 am
Знам в бързането не съм я написъл правилно. По късно ще напиша кода.
Титла: Arduino код?
Публикувано от: killara1 в Април 23, 2013, 11:44:32 am
Това успях да сътворя 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.
}

Сега си спомням че някъде четох за една функция която давала точно преди колко време е била включено ардуино платката, не знам да ли няма да ми свърши работа.
Титла: Arduino код?
Публикувано от: ZiGi88 в Април 23, 2013, 05:15:47 pm
Като начало:

Цитат
hour=hour=1
Титла: Arduino код?
Публикувано от: killara1 в Април 23, 2013, 05:53:06 pm
Благодаря поправих го.
Титла: Arduino код?
Публикувано от: emil74 в Април 23, 2013, 08:56:39 pm
Не съм се задълбочавал в кода, но не видях къде отброяваш време 1 секунда, за да увеличиш брояч секунди. Ако ползваш Delay, имай предвид, че операциите по обработка добавят време и импулсите ще са неточни, т.е. ще имаш натрупване на грешка.Желателно е да ползваш прекъсване от таймер.
Титла: Arduino код?
Публикувано от: killara1 в Април 23, 2013, 09:07:06 pm
Смисъл от какъв таймер.
Титла: Arduino код?
Публикувано от: emil74 в Април 23, 2013, 09:37:24 pm
Вграден таймер на ATMega. Прочети например:
http://www.instructables.com/id/Arduino-Timer-Interrupts/

Това пък е от страницата на Ардуино:
http://playground.arduino.cc/code/timer1
Титла: Arduino код?
Публикувано от: killara1 в Април 24, 2013, 11:55:35 pm
До тук добре, разбрах малко, но може ли да ми покажеш как да си свормирам кода.
Титла: Arduino код?
Публикувано от: killara1 в Май 06, 2013, 11:48:41 pm
Някой.
Титла: Arduino код?
Публикувано от: emil74 в Май 07, 2013, 01:59:54 pm
Формулирай точно алгоритъма и ще го направим. За да не се налага да се извлича алгоритъм от частично написан код. Така се увеличава шансът за грешка в новия алгоритъм.
Титла: Arduino код?
Публикувано от: booker в Май 08, 2013, 02:02:57 am
Ето една програма направена за две минути-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-я ден в точно определен час, минута и секунда.......