מד לחות אדמה V2 מבוסס ATtiny13

פרויקט של השעות הקטנות של הלילה השתדרג טיפה   slower, cheaper, smaller, better

1

2

 

אז במטרה לצמצם את הפרויקט שלי http://www.makers.co.il/mfs/showthread.php?t=3151
נכנסתי לאיביי והזמנתי ATtiny13A ו ATtiny85

כמובן שה 13 היה יותר זול וגם הגיע ראשון and oh boy כמה עבודה ולמידה עברתי כדי לגרום לזה לעבוד.
חלקים של הקוד עברו לקצת יותר low level כדי לצמצם בגודל, כמו שינה וdigitalWrite
גודל הקוד הסופי 920 בייט

על השינה למדתי ועשיתי "פורט" לATtiny13 מהפרויקט הנחמד הזה https://learn.sparkfun.com/tutorials…w-power-attiny

בעיות:

  • ATtiny13A מגיע עם 1K פלאש בלבד ולצמצם את גודל הקוד היה המכשול העיקרי
  • גם ה 13 וגם ה 85 מגיעים עם הרבה פחות פינים אז גם הייתי צריך לצמצם את הLDR ולא לבדוק אם יש אור .. אבל זה לא ממש מפריע לי
  • בtiny למיניהם אני לא יכול לחשב את המתח של הVCC כי ה בקר לא מסוגל לעשות זאת אז הייתי צריך להשתמש ב ADC אז העדפתי מתח של סוללה על פני אור במקום לחסוך סוללה לבזבז יותר

מורכב מ:

  • ATtiny13A + תושבת
  • מזלג לחות 😛 + נגד פול-אפ 10K
  • לד צהוב + נגד 680
  • כפתור TACT + נגד פול-אפ 10K
  • זוג נגדים לחלק את מתח הסוללה 1M ו560K (נגדים גדולים כדי לחסוך סוללה)
  • זוג סוללות כפתור 1.5V בטור (יוחלף ב CR2032)

משמעות קיום:
לתריע אם האדמה יבשה ע"י הבהוב לד -> ולהתריע אם הסוללה חלשה ע"י הבהוב שני.
מידת הלחות של האדמה ניתנת לכיול.

תיאור הפעולה:
מתעורר > מחליף analogReference ל INTERNAL כלומר 1.1V ולוקח מספר דגימות כדי לייצב את הקריאה, דוגם מתח סוללה, מחליף את הanalogReference ל DEFAULT כלומר VCC ולוקח מספר דגימות כדי לייצב את הקריאה ->
בודק אם כפתור כיול לחוץ {אם כן: מהבהב ומחכה ללחיצה שניה אשר תביא לדגימת המוליכות של האדמה ושמירה לEEPROM | אם לא: ממשיך} >
דוגם את מוליכות האדמה ומשווה לערך המכוייל {אם נמוך: מפליש את הלד} משווה את מתח הסוללה {אם נמוך: מפליש את הלד פעם נוספת} > חוזר לישון ל 8 שניות.

שינויים מיוחדים:

  • נצרבו פיוזים לבקר אשר שמים אותו על שעון 4.8Mhz פנימי ומכבים זיהוי מתח נמוך (Brown-out) כדי שיחסוך בסוללה ויעבוד כל עוד הוא יכול.
  • הפיוזים:
    low_fuses=0x79
    high_fuses=0xFF

צריכת אנרגיה וזמנים:
שינה של 7.61824 שניות במומוצע
ומצב ער של 81536 מיקרו-שניות בממוצע שזה 81.5 מילישניות

צריכה בשינה – 0.0068 מיליאמפר (6.8 מיקרו אמפר – עם האדרואינו פרו מיני היה 9 מיקרו אמפר)
צריכה כש-ער בלי הבהוב הלד – 1.43 מיליאמפר
צריכה כש-ער עם הבהוב הלד – 2.44 מיליאמפר

לא חישבתי זמן סוללה אבל יותר חסכוני מהפרויקט הקודם אז שנה++

הקוד:

קוד:
#include <EEPROM.h>#include <avr/sleep.h> //Needed for sleep_mode
#include <avr/wdt.h> //Needed to enable/disable watch dog timer


int lowerSoilValue = 0;
int voltage = 0;


void setup()
{
    // Setup Pins
    pinMode(0, OUTPUT);
    pinMode(3, OUTPUT);
    pinMode(1, INPUT);
    
    // Get Value from EEPROM
    lowerSoilValue = EEPROM.read(0) * 4 + EEPROM.read(1);


    // Sleep Setup
    set_sleep_mode(SLEEP_MODE_PWR_DOWN); //Power down everything, wake up from WDT
    sleep_enable();


}


void loop() 
{  
     wdt_disable(); //Turn off the WDT!
     ADCSRA |= (1<<ADEN); //Enable ADC
     
     // Battery Voltage Read
     // Switch Analog Reference to 1.1V Internal , take 5 readings that may be innacurate due to switching
    analogReference(INTERNAL);
    for(int i = 0; i<5; i++){ analogRead(A1); }
    voltage = analogRead(A1) * 3; // Final Reading
  
    // Switch back to default and take 5 readings that may be innacurate due to switching
    analogReference(DEFAULT);
    for(int i = 0; i<5; i++){ analogRead(A2); }


    // Programm Mode
    if (digitalRead(1) == HIGH){ 
    while(digitalRead(1) == HIGH){   // Blink until button released
        PORTB |= _BV(PB0);
        delay(50);
        PORTB &= ~_BV(PB0); 
       delay(50); 
      }
      while(digitalRead(1) == LOW){     // Continue blinking until button pressed again to programm
        PORTB |= _BV(PB0);
        delay(50);
        PORTB &= ~_BV(PB0); 
       delay(50); 
      }
      // Set pin 3 HIGH and take a double reading for accuracy, then set pin 3 LOW
      PORTB |= _BV(PB3);
      lowerSoilValue = analogRead(A2);
      lowerSoilValue = analogRead(A2);
      PORTB &= ~_BV(PB3);
      // Write values to EEPROM
      EEPROM.write(0, lowerSoilValue / 4);
      EEPROM.write(1, lowerSoilValue % 4);
    }  // END of programm mode


      // Set pin 3 HIGH and take a double reading for accuracy
      PORTB |= _BV(PB3);
      if (analogRead(A2) < lowerSoilValue){  // if reading is lower than progremmed value
        // Blink once
        PORTB |= _BV(PB0);
        delay(50);
        PORTB &= ~_BV(PB0);  
        
        // if voltage is low blink second time
        if(voltage < 2000){
            delay(50);
            PORTB |= _BV(PB0);
            delay(50);
            PORTB &= ~_BV(PB0); 
          }
        }
      // Set pin 3 LOW  
      PORTB &= ~_BV(PB3);  
      
      //Disable ADC, saves ~230uA
      ADCSRA &= ~(1<<ADEN); 
      
      // Sleep 
      setup_watchdog(9); //Setup watchdog to go off after 8sec
      sleep_mode(); //Go to sleep! 
}


//Sets the watchdog timer to wake us up, but not reset
//0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms
//6=1sec, 7=2sec, 8=4sec, 9=8sec
void setup_watchdog(int timerPrescaler) {
  if (timerPrescaler > 9 ) timerPrescaler = 9; //Limit incoming amount to legal settings


  byte bb = timerPrescaler & 7; 
  if (timerPrescaler > 7) bb |= (1<<5); //Set the special 5th bit if necessary


  //This order of commands is important and cannot be combined
  MCUSR &= ~(1<<WDRF); //Clear the watch dog reset
  WDTCR |= (1<<WDCE) | (1<<WDE); //Set WD_change enable, set WD enable
  WDTCR = bb; //Set new watchdog timeout value
  WDTCR |= _BV(WDTIE); //Set the interrupt enable, this will keep unit from resetting after each int
}

ליבה:
ליבה core13 קלילה במיוחד
http://forum.arduino.cc/index.php?topic=89781.0
http://sourceforge.net/projects/ard-core13/

מעגל:
Schematic

וידאו:
אולי … בקרוב…

הערות:
הATtiny13A נראה לי עדיף בסופו של דבר כי הוא מסוגל לעבוד במתחים נמוכים ממש שלא כמו ה86 שלפי הדף הוא עד 2.8V
יש את ADC0 שלא השתמשתי בו ויכלתי לשים עליו LDR בשביל זה אני צריך לכבות את פין RESET בפיוזים וזה ימנע ממני לצרוב עם ISP ובגלל שאין לי צורבים ואין לי ראש להיכנס ביינתים לצורבים HV זה ישאר ככה
אם אזכר במשהו אוסיף..

ומקווה שאהבתם