Timing Calculation attiny10

I am using the ATtiny10 MCU with Arduino 1.8.9. I have managed to get everything working except for the timing aspect of my application, which involves a delay timer. I can successfully read and send analog count values through UART, but I'm facing issues with the timing calculations. Since I'm using PB0 for UART, I can't get an accurate count for PB0. To obtain this count, I need to run separate tests and then write the code. While DipReading and Dip_State are functioning correctly, I'm having trouble with PotReading and the time delay calculations.

I need help in passing right values.
Assume delayValue =1000msec . This max value been set.
I have the pot which read this value and devide into range. the variable used to read the Pot is PotReading reading.

when pot position is 1 i,e means after 100Us Relay must be on.
Max delayValue =1000 when pot position is min it should give 10 value .
TimeDelay = (delayValue * PotReading)/10;

I need formula which we can handle this..

#include <avr/delay.h>
#include "debugSerial.h"
debugSerial dSerial;

// ADC channel definitions
#define POT_CHANNEL 0
#define DIP_CHANNEL 1
#define DIP4_CHANNEL 3

// Digital pin definitions
#define RELAY_PIN 2

#define DELAY_0_1MS    1   // 0.1 milliseconds
#define DELAY_1MS      1   // 1 millisecond
#define DELAY_100MS 100
#define DELAY_0_1SEC    100   // 100 milliseconds
#define DELAY_10MS 10
// Delay constants (in milliseconds)
#define DELAY_1SEC      1000
#define DELAY_10SEC     10000
#define DELAY_30SEC     30000
#define DELAY_1MIN      60000
#define DELAY_3SEC      3000
#define DELAY_3MIN      180000
#define DELAY_10MIN     600000
#define DELAY_30MIN     1800000
#define DELAY_1HR       3600000
#define DELAY_3HR       10800000
#define DELAY_10HR      36000000 // Added delay for 10 hours
#define DELAY_30HR      108000000
unsigned char PowerState = 1;
unsigned int delayValue = 0;
unsigned int PotReading = 0;
unsigned char Dip_State = 0;
int TimeDelay = 0;

void setup() {
  pinMode(POT_CHANNEL, INPUT);
  pinMode(DIP_CHANNEL, INPUT);
  pinMode(DIP4_CHANNEL, INPUT);
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);
}
void loop() {


  // digitalWrite(RELAY_PIN, LOW);
  PotReading = (analogRead(POT_CHANNEL) / 40) + 1;
  Dip_State = (analogRead(DIP4_CHANNEL) >= 700) ? 1 : 0;
  int DipReading = analogRead(DIP_CHANNEL);
  if (DipReading < 20) {
    delayValue = (Dip_State == 0) ? DELAY_1SEC : DELAY_1MIN;
  } else if (DipReading < 120) {
    delayValue = (Dip_State == 0) ? DELAY_10SEC : DELAY_10MIN;
  } else if (DipReading < 180) {
    delayValue = (Dip_State == 0) ? DELAY_3SEC : DELAY_3MIN;
  } else if (DipReading < 130) {
    delayValue = (Dip_State == 0) ? DELAY_30SEC : DELAY_30MIN;
  } else if (DipReading < 190) {
    delayValue = (Dip_State == 0) ? DELAY_1HR : DELAY_1HR;
  } else if (DipReading < 40) {
    delayValue = (Dip_State == 0) ? DELAY_3HR : DELAY_3HR;
  } else if (DipReading < 120) {
    delayValue = (Dip_State == 0) ? DELAY_10HR : DELAY_10HR;
  } else if (DipReading < 230) {
    delayValue = (Dip_State == 0) ? DELAY_30HR : DELAY_30HR;
  }
  PowerState = 0;
  TimeDelay = (delayValue * PotReading)/10;
  if (TimeDelay >= 100 && TimeDelay < 3000)
  {
    delayMicroseconds(TimeDelay);
  } else
  {
    delay(TimeDelay);
  }

  // Activate the relay
  digitalWrite(RELAY_PIN, HIGH);

}

I'm not familiar with the attiny10.

Just commenting on the fact that the delayValue variable is an unsigned int and can never hold anything larger than 65535.

I have changed int to unsigned long TimeDelay = 0; I have tried reading potvalue by assigning to different pin . i see below reading.
Another observation is if timing above 1min . if set timing to 2 min or 5 min relay trigger at 1Min only.
for lower value 1000msec set value . it trigger very fast . as soon power on it get turn on relay.

if simple LED blink i use . i would see proper 1Sec on and 1Sec off.

#include <avr/delay.h>
#include "debugSerial.h"
debugSerial dSerial;

// ADC channel definitions
#define POT_CHANNEL 0
#define DIP_CHANNEL 1
#define DIP4_CHANNEL 3

// Digital pin definitions
#define RELAY_PIN 2

#define DELAY_0_1MS    1   // 0.1 milliseconds
#define DELAY_1MS      1   // 1 millisecond
#define DELAY_100MS 100
#define DELAY_0_1SEC    100   // 100 milliseconds
#define DELAY_10MS 10
// Delay constants (in milliseconds)
#define DELAY_1SEC      1000
#define DELAY_10SEC     10000
#define DELAY_30SEC     30000
#define DELAY_1MIN      60000
#define DELAY_3SEC      3000
#define DELAY_3MIN      180000
#define DELAY_10MIN     600000
#define DELAY_30MIN     1800000
#define DELAY_1HR       3600000
#define DELAY_3HR       10800000
#define DELAY_10HR      36000000 // Added delay for 10 hours
#define DELAY_30HR      108000000
unsigned char PowerState = 1;
unsigned int delayValue = 0;
int PotReading = 0;
int CountValue = 0;
unsigned char Dip_State = 0;
unsigned long TimeDelay = 0;

void setup() {
  pinMode(POT_CHANNEL, INPUT);
  pinMode(DIP_CHANNEL, INPUT);
  pinMode(DIP4_CHANNEL, INPUT);
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);
}
void loop() {


  // digitalWrite(RELAY_PIN, LOW);
  CountValue = analogRead(POT_CHANNEL);

  if (CountValue <= 252) {
    PotReading = 10;
  } else if (CountValue <= 180) {
    PotReading = 9;
  } else if (CountValue <= 52) {
    PotReading = 8;
  } else if (CountValue <= 176) {
    PotReading = 7;
  } else if (CountValue <= 88) {
    PotReading = 6;
  } else if (CountValue <= 252) {
    PotReading = 5;
  } else if (CountValue <= 140) {
    PotReading = 4;
  } else if (CountValue <= 68) {
    PotReading = 3;
  } else if (CountValue <= 232) {
    PotReading = 2;
  } else if (CountValue <= 120) {
    PotReading = 1;
  } else {
    PotReading = 1;
  }

  Dip_State = (analogRead(DIP4_CHANNEL) >= 700) ? 1 : 0;
  int DipReading = analogRead(DIP_CHANNEL);
  if (DipReading < 20) {
    delayValue = (Dip_State == 0) ? DELAY_1SEC : DELAY_1MIN;
  } else if (DipReading < 120) {
    delayValue = (Dip_State == 0) ? DELAY_10SEC : DELAY_10MIN;
  } else if (DipReading < 180) {
    delayValue = (Dip_State == 0) ? DELAY_3SEC : DELAY_3MIN;
  } else if (DipReading < 130) {
    delayValue = (Dip_State == 0) ? DELAY_30SEC : DELAY_30MIN;
  } else if (DipReading < 190) {
    delayValue = (Dip_State == 0) ? DELAY_1HR : DELAY_1HR;
  } else if (DipReading < 40) {
    delayValue = (Dip_State == 0) ? DELAY_3HR : DELAY_3HR;
  } else if (DipReading < 120) {
    delayValue = (Dip_State == 0) ? DELAY_10HR : DELAY_10HR;
  } else if (DipReading < 230) {
    delayValue = (Dip_State == 0) ? DELAY_30HR : DELAY_30HR;
  }
  PowerState = 0;
  TimeDelay = (delayValue / PotReading);
  /*if (TimeDelay >= 100 && TimeDelay < 3000)
  {
    delayMicroseconds(TimeDelay);
  } else
  {
    delay(TimeDelay);
  }*/
 delay(TimeDelay);
  // Activate the relay
  digitalWrite(RELAY_PIN, HIGH);

}

I don't see any tiny10-specific features in use.
That should mean that you can compile and run the code on a Uno, for debugging purposes, where you have plenty of pins and a serial port to output values to see what they are.

this sort of methodology - debugging code on a much larger and more capable system than the final target - is very common.

1 Like

I wont see issue here . Only issue in getting count for PotReading. i think attiny10 is 8 bit and atmega328 is 10 bit resolution. that reason i am getting count range 0-255 and 0-1024 in uno
I am seeing weird behavior in PotReading. even its 20k pot. count value should get 0-255 properly. but when i print value i am getting improper. that what i used in the code.

#include <avr/delay.h>
#include "debugSerial.h"
debugSerial dSerial;

// ADC channel definitions
#define POT_CHANNEL 0
#define DIP_CHANNEL 1
#define DIP4_CHANNEL 3

// Digital pin definitions
#define RELAY_PIN 2

#define DELAY_0_1MS    1   // 0.1 milliseconds
#define DELAY_1MS      1   // 1 millisecond
#define DELAY_100MS 100
#define DELAY_0_1SEC    100   // 100 milliseconds
#define DELAY_10MS 10
// Delay constants (in milliseconds)
#define DELAY_1SEC      100
#define DELAY_10SEC     1000
#define DELAY_30SEC     3000
#define DELAY_1MIN      6000
#define DELAY_3SEC      300
#define DELAY_3MIN      18000
#define DELAY_10MIN     60000
#define DELAY_30MIN     180000
#define DELAY_1HR       360000
#define DELAY_3HR       1080000
#define DELAY_10HR      3600000 // Added delay for 10 hours
#define DELAY_30HR      10800000
unsigned char PowerState = 1;
unsigned int delayValue = 0;
int PotReading = 0;
int CountValue = 0;
unsigned char Dip_State = 0;
unsigned long TimeDelay = 0;

void setup() {
  pinMode(POT_CHANNEL, INPUT);
  pinMode(DIP_CHANNEL, INPUT);
  pinMode(DIP4_CHANNEL, INPUT);
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);
}
void loop() {

//PotReading=(analogRead(POT_CHANNEL)/40)+1;
  // digitalWrite(RELAY_PIN, LOW);
  CountValue = analogRead(POT_CHANNEL);

  if (CountValue <= 252) {
    PotReading = 1;
  } else if (CountValue <= 180) {
    PotReading = 2;
  } else if (CountValue <= 52) {
    PotReading = 3;
  } else if (CountValue <= 176) {
    PotReading =4;
  } else if (CountValue <= 88) {
    PotReading = 5;
  } else if (CountValue <= 252) {
    PotReading = 6;
  } else if (CountValue <= 140) {
    PotReading = 7;
  } else if (CountValue <= 68) {
    PotReading = 8;
  } else if (CountValue <= 232) {
    PotReading = 9;
  } else if (CountValue <= 120) {
    PotReading = 10;
  } else {
    PotReading = 10;
  }

  Dip_State = (analogRead(DIP4_CHANNEL) >= 700) ? 1 : 0;
  int DipReading = analogRead(DIP_CHANNEL);
  if (DipReading < 20) {
    delayValue = (Dip_State == 0) ? DELAY_1SEC : DELAY_1MIN;
  } else if (DipReading < 120) {
    delayValue = (Dip_State == 0) ? DELAY_10SEC : DELAY_10MIN;
  } else if (DipReading < 180) {
    delayValue = (Dip_State == 0) ? DELAY_3SEC : DELAY_3MIN;
  } else if (DipReading < 130) {
    delayValue = (Dip_State == 0) ? DELAY_30SEC : DELAY_30MIN;
  } else if (DipReading < 190) {
    delayValue = (Dip_State == 0) ? DELAY_1HR : DELAY_1HR;
  } else if (DipReading < 40) {
    delayValue = (Dip_State == 0) ? DELAY_3HR : DELAY_3HR;
  } else if (DipReading < 120) {
    delayValue = (Dip_State == 0) ? DELAY_10HR : DELAY_10HR;
  } else if (DipReading < 230) {
    delayValue = (Dip_State == 0) ? DELAY_30HR : DELAY_30HR;
  }
  PowerState = 0;
  TimeDelay = (delayValue * PotReading);
  /*if (TimeDelay >= 100 && TimeDelay < 3000)
  {
    delayMicroseconds(TimeDelay);
  } else
  {
    delay(TimeDelay);
  }*/
 delay(TimeDelay);
  // Activate the relay
  digitalWrite(RELAY_PIN, HIGH);

}

From what i see in your code loop, every outcome is "less than".

Method1

#include <avr/io.h>
#include <util/delay.h>

unsigned char PowerState = 1;
unsigned int delayValue = 0;
int PotReading = 0;
unsigned char Dip_State = 0;
unsigned long TimeDelay = 0;
// ADC channel definitions
#define POT_CHANNEL 0
#define DIP_CHANNEL 1
#define DIP4_CHANNEL 3

// Digital pin definitions
#define RELAY_PIN 2

#define DELAY_1SEC     10000
#define DELAY_10SEC    100000
#define DELAY_1MIN     60000
#define DELAY_10MIN    600000
#define DELAY_1HR      3600000

#define DELAY_3SEC     30000
#define DELAY_30SEC    300000
#define DELAY_3MIN     180000
#define DELAY_30MIN    1800000

#define DELAY_3HR      10800000
#define DELAY_10HR     36000000
#define DELAY_30HR     108000000

struct Range {
  uint16_t min;
  uint16_t max;
  uint16_t value;
};


// Range array for PotReading
const Range ranges[] = {
  {920, 1023, 50},
  {901, 919, 100},
  {830, 900, 150},
  {770, 829, 200},
  {740, 769, 250},
  {680, 739, 300},
  {620, 679, 350},
  {580, 619, 400},
  {525, 579, 450},
  {490, 524, 500},
  {430, 489, 550},
  {380, 429, 600},
  {345, 379, 650},
  {295, 344, 700},
  {250, 294, 750},
  {200, 249, 800},
  {140, 199, 850},
  {30, 139, 900},
  {0, 29, 1000}
};

void setup() {
  pinMode(POT_CHANNEL, INPUT);
  pinMode(DIP_CHANNEL, INPUT);
  pinMode(DIP4_CHANNEL, INPUT);
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);
}

void loop() {
  uint16_t CountValue = analogRead(POT_CHANNEL);

  // Find the corresponding PotReading value
  for (char i = 0; i < sizeof(ranges) / sizeof(ranges[0]); i++) {
    if (CountValue >= ranges[i].min && CountValue <= ranges[i].max) {
      PotReading = ranges[i].value;
      break;
    }
  }

  Dip_State = (analogRead(DIP4_CHANNEL) >= 700) ? 1 : 0;
  int DipReading = analogRead(DIP_CHANNEL);

  if (DipReading < 100) {
    delayValue = (Dip_State == 0) ? DELAY_1SEC : DELAY_1MIN;
  } else if (DipReading <= 200) {
    delayValue = DELAY_1HR; // Same for both Dip_State values
  } else if (DipReading <= 450) {
    delayValue = (Dip_State == 0) ? DELAY_3SEC : DELAY_3MIN;
  } else if (DipReading <= 550) {
    delayValue = DELAY_3HR; // Same for both Dip_State values
  } else if (DipReading <= 700) {
    delayValue = (Dip_State == 0) ? DELAY_10SEC : DELAY_10MIN;
  } else if (DipReading <= 820) {
    delayValue = DELAY_10HR; // Same for both Dip_State values
  } else if (DipReading <= 910) {
    delayValue = (Dip_State == 0) ? DELAY_30SEC : DELAY_30MIN;
  } else if (DipReading <= 1000) {
    delayValue = DELAY_30HR; // Same for both Dip_State values
  }

  TimeDelay = (delayValue * PotReading) / 1000;

  // Delay for the calculated TimeDelay
  delay(TimeDelay);

  // Activate the relay
  digitalWrite(RELAY_PIN, HIGH);

}

Method2

#include <avr/io.h>
#include <util/delay.h>

// ADC channel definitions
#define POT_CHANNEL 0
#define DIP_CHANNEL 1
#define DIP4_CHANNEL 3

// Digital pin definitions
#define RELAY_PIN 2

#define DELAY_1SEC     10000
#define DELAY_10SEC    100000
#define DELAY_1MIN     60000
#define DELAY_10MIN    600000
#define DELAY_1HR      3600000

#define DELAY_3SEC     30000
#define DELAY_30SEC    300000
#define DELAY_3MIN     180000
#define DELAY_30MIN    1800000

#define DELAY_3HR      10800000
#define DELAY_10HR     36000000
#define DELAY_30HR     108000000

struct Range {
  uint16_t min;
  uint16_t max;
  uint16_t value;
};

// Range array for PotReading
const Range ranges[] = {
  {920, 1023, 50},
  {901, 919, 100},
  {830, 900, 150},
  {770, 829, 200},
  {740, 769, 250},
  {680, 739, 300},
  {620, 679, 350},
  {580, 619, 400},
  {525, 579, 450},
  {490, 524, 500},
  {430, 489, 550},
  {380, 429, 600},
  {345, 379, 650},
  {295, 344, 700},
  {250, 294, 750},
  {200, 249, 800},
  {140, 199, 850},
  {30, 139, 900},
  {0, 29, 1000}
};

const Range Sec_HrRange[] =
{
  {0, 20, DELAY_1SEC},
  {20, 350, DELAY_1HR },
  {360, 460, DELAY_3SEC },
  {461, 600, DELAY_3HR },
  {601, 700, DELAY_10SEC },
  {701, 880, DELAY_10HR },
  {881, 920, DELAY_30SEC },
  {921, 1000, DELAY_30HR }

};

const Range Min_HrRange[] =
{
  {0, 20, DELAY_1MIN},
  {20, 350, DELAY_1HR},
  {360, 460, DELAY_3MIN},
  {461, 600, DELAY_3HR },
  {601, 700, DELAY_10MIN },
  {701, 880, DELAY_10HR },
  {881, 920, DELAY_30MIN },
  {921, 1000, DELAY_30HR }
};

unsigned char PowerState = 1;
unsigned int delayValue = 0;
int PotReading = 0;
unsigned char Dip_State = 0;
unsigned long TimeDelay = 0;

void setup() {
  pinMode(POT_CHANNEL, INPUT);
  pinMode(DIP_CHANNEL, INPUT);
  pinMode(DIP4_CHANNEL, INPUT);
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);
}
void loop() {
  // Read potentiometer value
  uint16_t CountValue = analogRead(POT_CHANNEL);

  // Find the corresponding PotReading value
  for (char i = 0; i < sizeof(ranges) / sizeof(ranges[0]); i++) {
    if (CountValue >= ranges[i].min && CountValue <= ranges[i].max) {
      PotReading = ranges[i].value;
      break;
    }
  }

  // Read DIP switch values
  Dip_State = (analogRead(DIP4_CHANNEL) >= 700) ? 1 : 0;
  uint16_t DipReading = analogRead(DIP_CHANNEL);

  // Set the delayValue based on DIP switch settings
  if (Dip_State == 1) {
    for (char i = 0; i < sizeof(Min_HrRange) / sizeof(Min_HrRange[0]); i++) {
      if (DipReading >= Min_HrRange[i].min && DipReading <= Min_HrRange[i].max) {
        delayValue = Min_HrRange[i].value;
        break;
      }
    }
  } else {
    for (char i = 0; i < sizeof(Sec_HrRange) / sizeof(Sec_HrRange[0]); i++) {
      if (DipReading >= Sec_HrRange[i].min && DipReading <= Sec_HrRange[i].max) {
        delayValue = Sec_HrRange[i].value;
        break;
      }
    }
  }

  // Adjust TimeDelay based on PotReading
  TimeDelay = (delayValue * PotReading) / 1000;

  // Delay for the calculated TimeDelay
  delay(TimeDelay);

  // Activate the relay
  digitalWrite(RELAY_PIN, HIGH);
}

These i thingi tried . code memory showing

ATtiny10 connected / Write C:\Users\user\AppData\Local\Temp\arduino_build_149415/ajit456.ino.hex
NVM enabled
chip erased
couldn't receive data:
program is too large

I wanted this logic in part2

  if (DipReading < 100) {
    delayValue = (Dip_State == 0) ? DELAY_1SEC : DELAY_1MIN;
  } else if ((DipReading>=100)&&(DipReading<=200)) {
   delayValue = (Dip_State == 0) ? DELAY_1HR : DELAY_1HR;
  } else if ((DipReading>=201)&&(DipReading<=450)){
   delayValue = (Dip_State == 0) ? DELAY_3SEC : DELAY_3MIN;
  } else if ((DipReading>=451)&&(DipReading<=550)) {
   delayValue = (Dip_State == 0) ? DELAY_3HR : DELAY_3HR;
  } else if ((DipReading>=551)&&(DipReading<=700)) {
     delayValue = (Dip_State == 0) ? DELAY_10SEC : DELAY_10MIN;
  } else if ((DipReading>=701)&&(DipReading<=820)) {
    delayValue = (Dip_State == 0) ? DELAY_10HR : DELAY_10HR;
  } else if ((DipReading>=821)&&(DipReading<=910)) {
     delayValue = (Dip_State == 0) ? DELAY_30SEC : DELAY_30MIN;
  } else if ((DipReading>=911)&&(DipReading<=1000)) {
    delayValue = (Dip_State == 0) ? DELAY_30HR : DELAY_30HR;
  }

I am planning to build a Taxi Meter using cost effective ATtiny44; but, I am developing the peripherals and Control Program of the meter using Arduino UNO. Once all are fixed, I will transfer everything to ATtiny44.