Go Down

Topic: Attiny85 Plant Watering system error (Read 215 times) previous topic - next topic

Anton3006

hey, I build my own plant watering system with an attiny85.
The problem: the code works perfectly on an arduino uno but not on the attiny85.

It don't turn on the pumps, maybe because it can't read the values well...


Attiny85 code:
Code: [Select]

//                  +-\/-+
// Ain0 (D 5) PB5  1|    |8  Vcc
// Ain3 (D 3) PB3  2|    |7  PB2 (D 2) Ain1
// Ain2 (D 4) PB4  3|    |6  PB1 (D 1) pwm1
//            GND  4|    |5  PB0 (D 0) pwm0
//                  +----+

#include <avr/sleep.h>    // Sleep Modes
#include <avr/power.h>    // Power management
#include <avr/wdt.h>      // Watchdog timer




#define SENSOR1 3 //Attiny2
#define SENSOR2 2 //Attiny3 = P2
#define PUMP1 0   //Attiny5
#define PUMP2 1   //Attiny6
#define RELAY 2   //Attiny 7

int SensorValue1; //Read Value
int SensorValue2; //
int ValueP1;      //Value percent
int ValueP2;      //



ISR (PCINT0_vect)
 {
 // do something interesting here
 }  // end of PCINT0_vect
 
// watchdog interrupt
ISR (WDT_vect)
{
   wdt_disable();  // disable watchdog
}  // end of WDT_vect

void resetWatchdog ()
{
  // clear various "reset" flags
  MCUSR = 0;     
  // allow changes, disable reset, clear existing interrupt
  WDTCR = bit (WDCE) | bit (WDE) | bit (WDIF);
  // set interrupt mode and an interval (WDE must be changed from 1 to 0 here)
  WDTCR = bit (WDIE) | bit (WDP3) | bit (WDP0);    // set WDIE, and 8 seconds delay
  // pat the dog
  wdt_reset(); 
}  // end of resetWatchdog
 

void setup()
{
  resetWatchdog ();  // do this first in case WDT fires
  pinMode(PUMP1, OUTPUT);
  pinMode(SENSOR1, INPUT);
  pinMode(PUMP2, OUTPUT);
  pinMode(SENSOR2, INPUT);
  pinMode(RELAY, OUTPUT);
}

void loop()
{
  digitalWrite(RELAY, HIGH);    //turn on sensors
  delay(1000);
  for(int x=0; x<10; x++)       //read 10 times and add
  {
    SensorValue1 = analogRead(SENSOR1);
    SensorValue2 = analogRead(SENSOR2);
    ValueP1 = ValueP1 + map(SensorValue1, 0, 400, 100, 0);
    ValueP2 = ValueP2 + map(SensorValue2, 0, 400 , 100, 0);
    delay(100);
  }
  ValueP1 = ValueP1/10;        //divide by 10 to get average value
  ValueP2 = ValueP2/10;
  while((ValueP1<60) || (ValueP2<60))  //if one of the plants need water do this
  {
    watering();
  }
  ValueP1 = 0;        //reset Values
  ValueP2 = 0;
  digitalWrite(RELAY, LOW);   // turn off sensors
  for(int x=0; x<1; x++)      //set to sleep for x times 10 sec
  {
    goToSleep ();
  }
}


void watering()
{
  SensorValue1 = analogRead(SENSOR1);   //read sensor values
  SensorValue2 = analogRead(SENSOR2);
  ValueP1 = map(SensorValue1, 0, 400, 100, 0);  //map to percent // 0 to 400 because this is the range for the perfect soil moist
  ValueP2 = map(SensorValue2, 0, 400 , 100, 0);
 
  if(ValueP1<60)
  {
    digitalWrite(PUMP1, HIGH);   //turn on pump for first plant
  }
  else
  {
    digitalWrite(PUMP1, LOW);   //turn of if enough water
  }

  if(ValueP2<60)
  {
    digitalWrite(PUMP2, HIGH);
  }
  else
  {
    digitalWrite(PUMP2, LOW);
  }
  delay(1000);
}


void goToSleep ()
  {
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);
  ADCSRA = 0;            // turn off ADC
  power_all_disable ();  // power off ADC, Timer 0 and 1, serial interface
  noInterrupts ();       // timed sequence coming up
  resetWatchdog ();      // get watchdog ready
  sleep_enable ();       // ready to sleep
  interrupts ();         // interrupts are required now
  sleep_cpu ();          // sleep               
  sleep_disable ();      // precaution
  power_all_enable ();   // power everything back on
  }  // end of goToSleep



Arduino Uno code:
Code: [Select]

#define SENSOR1 0
#define SENSOR2 1
#define PUMP1 9
#define PUMP2 10
#define RELAY 8

int SensorValue1; //
int SensorValue2; //
int ValueP1;      //
int ValueP2;      //


void setup()
{
  Serial.begin(9600);
  pinMode(PUMP1, OUTPUT);
  pinMode(SENSOR1, INPUT);
  pinMode(PUMP2, OUTPUT);
  pinMode(SENSOR2, INPUT);
  pinMode(RELAY, OUTPUT);
}

void loop()
{
  digitalWrite(RELAY, HIGH);
  Serial.println("RELAY=ON");
  delay(1000);
  for(int x=0; x<10; x++)
  {
    SensorValue1 = analogRead(SENSOR1);
    SensorValue2 = analogRead(SENSOR2);
    ValueP1 = ValueP1 + map(SensorValue1, 0, 400, 100, 0);
    ValueP2 = ValueP2 + map(SensorValue2, 0, 400 , 100, 0);
    delay(100);
  }
  ValueP1 = ValueP1/10;
  ValueP2 = ValueP2/10;
  Serial.print(SensorValue1);
  Serial.print(" | ");
  Serial.println(ValueP1);
  Serial.print(SensorValue2);
  Serial.print(" | ");
  Serial.println(ValueP2);
  while((ValueP1<60) || (ValueP2<60))
  {
    Serial.println("WATERING");
    watering();
  }
  digitalWrite(RELAY, LOW);
  Serial.println("RELAY=OFF");
  for(int x=0; x<3; x++)
  {
    delay(1000);
    Serial.println(x);
  }
}


void watering()
{
  SensorValue1 = analogRead(SENSOR1);
  SensorValue2 = analogRead(SENSOR2);
  ValueP1 = map(SensorValue1, 0, 400, 100, 0);
  ValueP2 = map(SensorValue2, 0, 400 , 100, 0);
  Serial.print(ValueP1);
  Serial.print(" | ");
  Serial.println(ValueP2);
  if(ValueP1<60)
  {
    digitalWrite(PUMP1, HIGH);
    Serial.println("PUMP1=ON");
  }
  else
  {
    digitalWrite(PUMP1, LOW);
    Serial.println("PUMP1=OFF");
  }

  if(ValueP2<60)
  {
    digitalWrite(PUMP2, HIGH);
    Serial.println("PUMP2=ON");
  }
  else
  {
    digitalWrite(PUMP2, LOW);
    Serial.println("PUMP2=OFF");
  }
  delay(1000);
}


The sleepmode is from here(but I don't think this is the problem):http://gammon.com.au/forum/?id=11497&reply=6#reply6

I'm using this type of sensor:https://www.amazon.com/Kuman-Moisture-Compatible-Raspberry-Automatic/dp/B071F4RDHY/ref=sr_1_4?ie=UTF8&qid=1544797339&sr=8-4&keywords=soil+moisture+sensor

I attached my cuircitdiagramm(LED should be pumps)

please help me and excuse my bad english, I'm from germany



pert

There was a possible cause of the problem suggested in the GitHub issue report:
https://github.com/arduino/Arduino/issues/8301#issuecomment-447353072
Quote
You are probably using ATTinyCore. Quoting from the "Quick Gotcha list":

Quote
When using analogRead(), use the A# constant to refer to the pin, not the digital pin number.

Anton3006

Thank you, but can you please say it in other words or write down, what I have to write in the code? Would be very nice

DrAzzy

#3
Dec 14, 2018, 11:54 pm Last Edit: Dec 14, 2018, 11:55 pm by DrAzzy
You cannot pass a digital pin number to analogRead(). Passing a number will read the ANALOG pin of that number. If you use the A# constants, eg, A1, A2, etc, that will work with both digitalRead/pinMode and analogRead; for you pins 2 and 3 are A1, and A3 respectively.

See part specific documentation for pin functions:

https://github.com/SpenceKonde/ATTinyCore/blob/master/avr/extras/ATtiny_x5.md

ATTinyCore for x4/x5/x61/x7/x8/x41/1634/828/x313 megaTinyCore for the megaavr ATtinies - Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny breakouts, mosfets, awesome prototyping board in my store http://tindie.com/stores/DrAzzy

Anton3006

Hm, I changed the pinsĀ“, but I dont think this is the problem. I powered the board, when the sensors are not in soil or water the neverything worked like it should: the pumps got power, the relay stayed on and after putting the sensors in water pumps and relay turned off, then the attiny went to sleep but after taking the sensors out again it only turned on the relay to check the values and then go back to sleep, even if it should turn on the pumps again...

Go Up