The following assumes that the behavior occurs after a reset or powercycle, not just after uploading fresh code;
What is count now, when you print it? If nothing is being written to the EEPROM at all, we would expect to read 0xFFFF, -1 for an unsigned integer.
If you're reading 0xFFFF (-1), then you should be suspicious that you're not writing it at all, or it is experiencing a hard reset upon writing.
If it's instead reading 0, that implies that somehow you wrote 0 to it, or the device is experiencing a hard reset upon writing, or that you aren't correctly reading it at power on.
You can verify that it's not resetting upon an attempted write (which renders the results of the write unpredictable) by simply having the chip do something distinctive in setup (eg, turn a led on, delay for a second, turn it off, and don't turn the LED on for any other reason, so any time the light goes on, you know the board has reset). In this context, I would expect that it would be almost always caused by failure to include a 0.1uF ceramic capacitor for bypass/decoupling between Vdd and Gnd; No digital integrated circuit should be expected to work without a decoupling cap unless it is documented explicitly that one is not required. Many of the classic AVRs (though not all) highlight the importance of this in the datasheet, thought the tiny85 does not, though it also doesn't say that you don't need one. And I happen to know from experience that it cannot be used without any decoupling. I think this discrepancy can be explained on the grounds that they assume basic electrical design practices on the part of designers using their parts, including that the power rail has some enough decoupling on the board that Vdd is reasonably stable. Without decoupling capacitors, because a digital circuit can change almost instantly from a sleep mode using under a microamp, to a full function mode drawing thousands of times that, the supply voltage "seen" by the chip will sharply drop when this occurs - current though a wire cannot change instantly, due to the parasitic inductance that any wire or other conductor has, so the voltage across the power rails next to the chip falls when the current sharply increases, as it does in normal operation of a digital IC. This is solved by putting a small ceramic capacitor between each power/ground pair of pins, as close to the chip as possible (long leads on the ceramic cap defeat the point of a decoupling cap - the distance you get total, between the pins of the chip is a few inches (in some - admittedly not-identical - conditions that were documented in a rather nice whitepaper I read, they describe the measurements of the effectiveness of a capacitor at filtering noise near the freqencies that we'd expect to see as they changed the distance to the cap, and by like 2 or 3 inches (2-3 inches each way, to be clear). the graph with the cap looked the same as without it, while that was very much not the case for a closer capacitor).
There are a few things that give me pause, though I don't use EEPROM.get/put much myself.
I see you using EEPROM.get() in two different ways
EEPROM.get(eeAddress, Count); //get data from selected EEPROM address
// and...
Count = EEPROM.get(eeAddress, Count); //get data from selected EEPROM address
// Certainly, from a good practices perspective, this should not be done
// you shouldn't have such stylistic inconsistencies...
// though I can't see why either of them wouldn't work.
if (digitalRead(LDR)==HIGH){
//body A
}
else if(digitalRead(LDR)==LOW){
//body B
These lines are technically hazardous; you expect that either bodyA or body B would run. But that is not always what will happen. With that code you read from the pin. If it's high, you do body A, otherwise, you read the pin again, and if it's low on this second read, do body B. I think you just wanted an else, so that you'd always get one or the other, never neither... Also, your code styling...
// USE PROPER INDENTATION! Every level of curly braces that you're inside of should be
// represented with 1 tab (2 spaces) of indentation. This convention (equal indentation for equal
// number of nested blocks, and either all tabs or all spaces for indentation, is universal.
// There is also a fairly strong majority opinion in favor of spaces rather than tabs).
// The other stylistic suggestions are things that some people might not agree on...
if (digitalRead(LDR) == HIGH) { // space between an operator and the operrands
// Whether to put a space after * and & when they appear as the unary (reference and
//dereference) operators is debatable, and there isn't a clear consensus, so I don't take a
// postion on those for others' code, as if you do the other operators, you're free from the
// unreadability quagmire I'm trying to steer folks away from; just do it consistently.
//body A
} else { // space before the opening curly brace greatly improves readability.
// I also put the else or else if on the same line as the previous closing brace; this is a tradeoff
// between the readability benefits of spreading the lines out, and those of fitting more of the
// file onto the screen at a time.
//body B
}
// And on that note, nobody ever does
++ Count;
// They do
Count++; //again, there isn't a consensus on whether to put a space between the ++ operator
// and the variable name; but I rarely see it, and don't do it.
// In general, postincrement and postdecrement are very common. Preincrement is rarely seen,
// and when it is, there's a reason. predecrement is not exotic to see in pointers, though I wouldn't
// say it's common either.
// Regardless of this, when you have a choice of two C constructs that will do the same thing for
// your application, and one of them doesn't have some sneaky advantage, don't do the wierd one.
// That makes people (including yourself months from now) reading it see the uncommon way
// and assume that there *was* some sneaky advantage.
Finally, I also would note that your system is absolutely hammering address 0. You only get 100k rewrites per EEPROM cell. Rewriting the EEPROM every 10 seconds you'd have only 11 days or so before your EEPROM was no longer within spec and may not work. My understanding is that when the EEPROM was partly "worn out", the parts of the EEPROM that had been accessed excessively would either always read as 1 or always read 0 - I think the latter. A runaway sketch that just sat there writing to a fixed address as fast as it could (3.4ms per rewrite) like this one, could exhaust the spec'ed eeprom life in just 6 minutes; That's not a strangely long time to have known non-working code on a board during development; so you can't upload any old code that may write to the EEPROM without taking some care that it couldn't sit there rewriting an address until it dies.
void loop() {
static byte t = 0;
EEPROM.write(0, t++); //every pass through loop will write a number to address 0.
}
If the problem does not manifest when the chip is reset in some way, but does manifest when new code is uploaded, and you are uploading the code via an ISP programmer (as we recommend for all t85s that are not digispark-clones*
). (If that behavior was seen when uploading through a bootloader, that's a bootloader other than what the core ships with), the problem is failure to "burn bootloader" with the desired options selected from the tools -> submenus; the applicable options are marked (Burn bootloader required to apply) or something similar to that (as much of that as I was comfortable with the length of the menu names; I forget whether the applicable options included any with names that were hard to make short on ATTC; that was what shaped the length of the parenthetical note on modern AVRs supported by mTC and DxC)
*
- Digispark clones (like any micronucleus bootloader for an otherwise supported part) are supported, as you likely know, but use a different "board definition"; many people post asking for support with a digispark-alike without mentioning that they're using such a part - particularly for the t85, as digisparks are so common that newbies don't always realize that that is not the normal configuration that people are assuming while answering. I'm pretty sure you're not using a digispark, but this is something that bears mention: 2 of the pins on the USB connector of those parts are tied to the USB lines, so they can't be used as inputs when the device is connected to a computer or even to some USB phone chargers (due to a "passive power supply" scheme they use to tell the connected device how much current it can provide by connecting the data lines to voltage dividers, and the voltages on the pins were read by early phones to enable the faster-charging modes, used before QC and USB-PD, which use the digital USB protocol proper)
**
- I firmly oppose your convention of having a pin that is not the hardware reset pin being named "RST" or "Reset", simply on the grounds that a name should refer to a specific object, concept, etc as unambiguously as possible. Atmel->Microchip has already claimed "Reset" and "RST", thus an application specific pin shouldn't be referred to in the same way. Especially because the hardware reset pin can be made into an I/O pin ***
(this also prevents ISP programming), Making the reset pin into an I/O pin is common among hobbyists on exactly one part: The tiny85, because that's how the original digispark boards shipped; the official ones are long gone, and the clones generally don't disable reset (this is an improvement IMO, since it's hard to enable reset if it's disabled, but easy to disable if it's enabled. Reset pins made into I/O also suck at the output part; they're around 20-30x the strength of the pullup, but a normal output pin is 20-30x the strength of the reset-as-output****
) digispark boards. It is virtually unheardof among hobbyists on anything else (okay, not unheardof, everyone's heard of it, but only in the context of accidentally writing garbage to the fuses such that reset was disabled and they couldn't reprogram the parts), since the tiny85, yes, is very pin-constrained, and since they had the ability to drive home some homogeneity through their high profile kickstarter campaign, and of course since they use a bootloader, they successfully shipped the official digisparks with reset disabled, and ran the bootloader only after a POR, hence the "replug within 8 seconds". I have never encountered a digispark clone, including ATtiny167 Digispark Pro clones and the MHET Tiny88 board where they had disabled reset. And this paragraph illustrates my point, as I was preparing a screed on reset as I/O before realizing that's not what you were doing.
***
- an interesting bit of trivia: On a classic AVR, with reset enabled, the RST pin will always read LOW. With reset disabled, of course, this isn't true; they reflect the state of the pin. Thus, one can more expediently verify that reset is or isn't disabled at startup by turning on the pullup of RST. waiting a bit, and then reading the pin - if it's LOW, reset must be enabled. Thinking about it now, there may be an even easier method for app code to detect the reset disabled-ness or lack thereof - if they have the bits in DDx/PORTx forced low, then that whole waiting game could be skipped by simply immediately testing whether that bit in PORTB stayed set. I don't know if the registers work like that; I know they do on modern AVRs.
****
- these numbers are quite rough - there isn't a single number that reflects the strength of an I/O pin driver or pullup - "strength" is a function of the voltage drop, plus operating conditions like vdd and temperature; it's a curve on a graph. As it happens, the specs that Microchip/Atmel (I don't think they've updated the typical characteristic graphs since the buyout, so the blame lies with Atmel) supplies seem to be designed to make comparisons between reset-as-i/o, normal i/o, and pullup strength as hard as possible. Reset as I/O is given at -40/0/85C. the other two at -40/25/85C. The reset and normal I/O pins are shown on graphs with current on X and voltage on Y, the pullup strength is given as uA on Y and voltage on X (though it changes considerably less as voltage changes than output strength)