Welcome to Laser Pointer Forums - discuss green laser pointers, blue laser pointers, and all types of lasers

Buy Site Supporter Role (remove some ads) | LPF Donations

Links below open in new window

FrozenGate by Avery

Anyone familiar with Attiny13 programming?

I looked into it and the 85 does have runtime addressable EEPROM. I'm learning the functions for it now. When I write up the program I'll test it out too. Should be easy enough to implement.
 





I looked into it and the 85 does have runtime addressable EEPROM. I'm learning the functions for it now. When I write up the program I'll test it out too. Should be easy enough to implement.

Awesome.

Dumb question - how the heck does the avr programmer attach to the smd chip for programming?
 
I need to know the exact package version you are using. The short answer is they make press-on tools that go over the chip and contact the pins. The less short answer is you make a breakout board and hone your precision soldering skills by soldering super fine wire onto the pins/pads. I'd go with the professional tool if this is more than a one-of. P.s.; this is why I went with the ATT85 PDIP and an arduino. The arduino acts as a bootloader/AVR-ISP and has a REALLY good programming IDE (PC program for making uC programs) for beginners.

About the non-volatile memory; these uCs have a very limited number of read/write cycles for the EEPROM memory. You can literally burn out the entire memory chip in ~7mins if you screw up your code. There are two semi-ok methods of preventing this and I'll experiment with which works better. I know one works fine (write-access limiting) but it literally removes the ability to write to the memory after the program has tried to write to it X amount of times. For your last-position-memory application this wouldn't work great as it would result in a largely random "save point" depending on useage characteristics. The other way involves writing to the memory each time that the button press is detected and just living with a limited lifespan of button clicks. Again though, the coding here has to be precise if you don't want to brick the chip. I can explain in further detail if you would like.

Also, let me know if you want me to comment out this program when I flesh it, so you can use it as a learning tool as well.
 
Presumably we can guard by only putting a write event inside the button function, and then only putting a read at the very beginning of the startup, at the end of a button press. No?

When you say limited, are you talking hundreds, thousands, millions?
 
Presumably we can guard by only putting a write event inside the button function, and then only putting a read at the very beginning of the startup, at the end of a button press. No?

When you say limited, are you talking hundreds, thousands, millions?

Yeah, that's the way that I think will work better; when the button press triggers an increment we make it write to memory as well.

They're stated good for 100k read/writes. Now, here's the thing; I'm not sure if that is only when the bits are changed (read and overwrite with equivalent data doesn't count) or all accesses. It would mean a big difference. If I put the read in the Void Setup() then it should dramatically cut read events too, but accidentally holding down the button would eat up writes.
 
But even then, it will only eat up writes at a rate limited by the debouncing function, correct? So not too horrible.
 
Righto. It would be limited in rate by the debounce subroutine's limiter, but no hard limiter. I think it will do fine honestly.

I finished the program but don't have time to test it out today. I'm busy doing just a few things...
-rebuilding a laptop as a surprise gift for my wife
-reworking an ATX psu as a bench supply
-Design Consultation on a new electrifying project by Fiddy
-Programming/Design Consultation and research on a major project to reverse engineer and create a private server for a shutdown MMO
-rebuilding my 3kW SSTC.

Btw, it comes to ~2.5kB so no way it will fit on the ATT13, gotta be a better uC (I recommend the 85).

Do you want me to post the program code here or upload it for private download or email it to you or...?
 
Last edited:
Btw, it comes to ~2.5kB so no way it will fit on the ATT13, gotta be a better uC (I recommend the 85).

Do you want me to post the program code here or upload it for private download or email it to you or...?

Posting it here is cool. I'm a sharey open kind when it comes to that stuff :)

I've ordered some ATTiny85 chips, like this one as well as a couple DIP versions, just for initial testing. Then I ordered a socket for the surface mount package here.

I've patched the ATTiny85 into my schematic properly now (or at least, more properly than representing it with a big pink square). How did I do?

revised.png
 
Well, a few things:

1) Which PortB terminal is used is largely determined by what you want to use it for and the pinout. For example some of the lines are used by the ISP AVR to program the chip and thus when you're using a SMD package won't let you program the chip because of on-board components you would be using to actually utilize the chip. So you then have to pick a different pin for that purpose. Similarly, the Reset pin can be used as a data line, and issues arise. In the code I put which pins/PortB lines work best for what, you'd have to translate that to the SMD version pinout.

2) Your button switch is shown as a pull-down switch, but you'd really want to use it as a pull-up switch since the default state is internal pull-down on these chips. You can set it in code to change the inputs to internal pull-up on and then use pull-down switches but this decreases the current capacity of the I/O lines because it uses a shared power architecture. You can pull ~40mA from a single I/O line but something like 5mA per line from each if using all (totaling to only ~30mA), and less if using internal pull ups. So, proper form would be like a 680k resistor between input pin and ground and then you switch the 5v line to the input pin (the chip has sufficient high input impedance).

Cool. I didn't know if you wanted to share it or not. Since I consider this commission work I relinquish rights to you. I'll post it here:

Code:
// RHD's TTL Color Selector
// Programming by Matt "Sigurthr" Giordano 08/13/2014
// www.SigurthrEnterprises.com
// Sigurthr@SigurthrEnterprises.com

// ATTiny85 Physical Pinout - innermost designation is code addressable
//                   _______
// Reset           _|  |_|  |_   Vcc
// ADC3 Pin3   3   _|       |_ 2 Pin2 ADC1
// ADC2 Pin4  A2   _| ATT85 |_ 1 Pin1 Digital-1
// Gnd             _|       |_ 0 Pin0 Digital-0
//                  |_______|
  

#include <EEPROM.h> // include the EEPROM Memory library

int PressDetects = 0;
int ButtonPin = 3; // see pinout
int ColorOnePin = 0; // see pinout
int ColorTwoPin = 1; // see pinout
int ColorThreePin = 2; // see pinout
int MemVar;
int ButtonPinState;
int ColorChoice;
int MemoryLocation = 1;
unsigned int TriggerCount = 10; // threshold for debounce

void setup (){ // this subroutine runs once upon startup
  MemVar = EEPROM.read(MemoryLocation); // read EEPROM on power on
  pinMode (0, OUTPUT); // set pin 0 to output
  pinMode (1, OUTPUT); // set pin 1 to output
  pinMode (2, OUTPUT); // set pin 2 to output
  pinMode (3, INPUT); // set pin 3 to input
}

void loop(){ // this subroutine runs continuously after setup finishes
  ButtonPinState = digitalRead(ButtonPin);  // read ButtonPin to ButtonPinState  
  if (MemVar == 0 || 255){  // first time an EEPROM is read it reads as 255
    MemVar = 1;
  }
  if (ButtonPinState == HIGH){ // when ButtonPinState is HIGH...
    ++ PressDetects; // increment detection variable
  }
  if (PressDetects >= TriggerCount) { // when threshold is exceeded...
    ++ MemVar; // increment memory variable
    PressDetects = 0; // reset button detector
    EEPROM.write(MemoryLocation, MemVar); // write color to memory    
    if (MemVar >= 9){ // on 9th button press...
      MemVar = 1; // reset color
    }
  }
  if (MemVar == 8){ // on 8th button press...
    ColorChoice = random(1, 7); // choose random color
  }
  else {  // if MemVar != 0,8,9,10, or larger...
    ColorChoice = MemVar;
  }
  if (ColorChoice == 1){
    digitalWrite(ColorOnePin, HIGH);
    digitalWrite(ColorTwoPin, HIGH);
    digitalWrite(ColorThreePin, HIGH);
  }
  if (ColorChoice == 2){
    digitalWrite(ColorOnePin, HIGH);
    digitalWrite(ColorTwoPin, LOW);
    digitalWrite(ColorThreePin, LOW);
  }
  if (ColorChoice == 3){
    digitalWrite(ColorOnePin, HIGH);
    digitalWrite(ColorTwoPin, HIGH);
    digitalWrite(ColorThreePin, LOW);
  }  
  if (ColorChoice == 4){
    digitalWrite(ColorOnePin, LOW);
    digitalWrite(ColorTwoPin, HIGH);
    digitalWrite(ColorThreePin, LOW);
  }
  if (ColorChoice == 5){
    digitalWrite(ColorOnePin, LOW);
    digitalWrite(ColorTwoPin, HIGH);
    digitalWrite(ColorThreePin, HIGH);
  }
  if (ColorChoice == 6){
    digitalWrite(ColorOnePin, LOW);
    digitalWrite(ColorTwoPin, LOW);
    digitalWrite(ColorThreePin, HIGH);
  }
  if (ColorChoice == 7){
    digitalWrite(ColorOnePin, HIGH);
    digitalWrite(ColorTwoPin, LOW);
    digitalWrite(ColorThreePin, HIGH);
  }
}

Oh and for programming socket I meant more like this:

http://www.ebay.com/itm/US-EEprom-C...1130960881&pt=Motors_Automotive_Tools&vxp=mtr

http://www.ebay.com/itm/SOIC8-SOP8-...516?pt=LH_DefaultDomain_0&hash=item2a3fd4516c

that way you can do it before and after it is soldered to the board (for updates/troubleshooting).
 
Last edited:
Code:
That's awesome!

You need to PM me your address. But also, I think I owe you something cooler than a couple DC DC converters and battery clips!

A couple revisions - let me know what you think.

Shouldn't:

Code:
    EEPROM.write(MemoryLocation, MemVar); // write color to memory
    if (MemVar >= 9){ // on 9th button press...
      MemVar = 1; // reset color
    }

Instead be:

Code:
    if (MemVar >= 9){ // on 9th button press...
      MemVar = 1; // reset color
    }
    EEPROM.write(MemoryLocation, MemVar); // write color to memory

And then I think the current arrangement will cause the the color output on the random setting to just appear white, because it will randomly change color multiple times per second. What I'd invision instead, is a situation where the randomization only occurs once per powerup. So I think the randomization should be moved into the button press, and then duplicated into startup as well. Let me know if this makes sense:

Code:
// RHD's TTL Color Selector
// Programming by Matt "Sigurthr" Giordano 08/13/2014
// www.SigurthrEnterprises.com
// Sigurthr@SigurthrEnterprises.com

// ATTiny85 Physical Pinout - innermost designation is code addressable
//                   _______
// Reset           _|  |_|  |_   Vcc
// ADC3 Pin3   3   _|       |_ 2 Pin2 ADC1
// ADC2 Pin4  A2   _| ATT85 |_ 1 Pin1 Digital-1
// Gnd             _|       |_ 0 Pin0 Digital-0
//                  |_______|
  

#include <EEPROM.h> // include the EEPROM Memory library

int PressDetects = 0;
int ButtonPin = 3; // see pinout
int ColorOnePin = 0; // see pinout
int ColorTwoPin = 1; // see pinout
int ColorThreePin = 2; // see pinout
int MemVar;
int ButtonPinState;
int ColorChoice;
int RandomChoiceA;
int RandomChoiceB;
int RandomChoiceC;
int MemoryLocation = 1;
unsigned int TriggerCount = 10; // threshold for debounce

void setup (){ // this subroutine runs once upon startup
  MemVar = EEPROM.read(MemoryLocation); // read EEPROM on power on
  pinMode (0, OUTPUT); // set pin 0 to output
  pinMode (1, OUTPUT); // set pin 1 to output
  pinMode (2, OUTPUT); // set pin 2 to output
  pinMode (3, INPUT); // set pin 3 to input
  if (MemVar == 8){ // if we're set on the random mode...
    RandomChoiceA = random(1, 2); // choose HIGH/LOW randomly
    RandomChoiceB = random(1, 2); // choose HIGH/LOW randomly
    RandomChoiceC = random(1, 2); // choose HIGH/LOW randomly
  }

}

void loop(){ // this subroutine runs continuously after setup finishes
  ButtonPinState = digitalRead(ButtonPin);  // read ButtonPin to ButtonPinState  
  if (MemVar == 0 || 255){  // first time an EEPROM is read it reads as 255
    MemVar = 1;
  }
  if (ButtonPinState == HIGH){ // when ButtonPinState is HIGH...
    ++ PressDetects; // increment detection variable
  }
  if (PressDetects >= TriggerCount) { // when threshold is exceeded...
    ++ MemVar; // increment memory variable
    PressDetects = 0; // reset button detector
    if (MemVar >= 9){ // on 9th button press...
      MemVar = 1; // reset color
    }
    EEPROM.write(MemoryLocation, MemVar); // write color to memory    
    if (MemVar == 8){ // on 8th button press...
      RandomChoiceA = random(1, 2); // choose HIGH/LOW randomly
      RandomChoiceB = random(1, 2); // choose HIGH/LOW randomly
      RandomChoiceC = random(1, 2); // choose HIGH/LOW randomly
    }
  }
  if (MemVar == 8){ // on 8th button press...
    if (RandomChoiceA == 1){
      digitalWrite(ColorOnePin, LOW);
    else {
      digitalWrite(ColorOnePin, HIGH);
    }
    if (RandomChoiceB == 1){
      digitalWrite(ColorTwoPin, LOW);
    else {
      digitalWrite(ColorTwoPin, HIGH);
    }
    if (RandomChoiceC == 1){
      digitalWrite(ColorThreePin, LOW);
    else {
      digitalWrite(ColorThreePin, HIGH);
    }
  }
  else {  // if MemVar != 0,8,9,10, or larger...
    ColorChoice = MemVar;
  }
  if (ColorChoice == 1){
    digitalWrite(ColorOnePin, HIGH);
    digitalWrite(ColorTwoPin, HIGH);
    digitalWrite(ColorThreePin, HIGH);
  }
  if (ColorChoice == 2){
    digitalWrite(ColorOnePin, HIGH);
    digitalWrite(ColorTwoPin, LOW);
    digitalWrite(ColorThreePin, LOW);
  }
  if (ColorChoice == 3){
    digitalWrite(ColorOnePin, HIGH);
    digitalWrite(ColorTwoPin, HIGH);
    digitalWrite(ColorThreePin, LOW);
  }  
  if (ColorChoice == 4){
    digitalWrite(ColorOnePin, LOW);
    digitalWrite(ColorTwoPin, HIGH);
    digitalWrite(ColorThreePin, LOW);
  }
  if (ColorChoice == 5){
    digitalWrite(ColorOnePin, LOW);
    digitalWrite(ColorTwoPin, HIGH);
    digitalWrite(ColorThreePin, HIGH);
  }
  if (ColorChoice == 6){
    digitalWrite(ColorOnePin, LOW);
    digitalWrite(ColorTwoPin, LOW);
    digitalWrite(ColorThreePin, HIGH);
  }
  if (ColorChoice == 7){
    digitalWrite(ColorOnePin, HIGH);
    digitalWrite(ColorTwoPin, LOW);
    digitalWrite(ColorThreePin, HIGH);
  }
}

And then I've switched the IC to a DIP8 version, and I'll just use a socket for now. Eventually, I'll go SMD, and program the chip before reflowing, but for now, I'll prototype the board with DIP8. Here's a revised view of that part of the schematic, let me know if this makes sense:

attachment.php


So is the socket that I ordered here (Fine SOIC8 SOP8 to DIP8 EZ Programmer Adapter Socket Converter Module 150mil | eBay) not one that can be connected/disconnected? It's hard to tell how it works from the photo, but it looked to me like an SMD part could be pressed in, creating a connection to the individual through-hole DIP-8 clone on the bottom, programmed, and then released from the clip to reflow onto the board.

I only ask because $17 + $7 shipping for this one (US EEPROM Clip SOIC 8 SMD Programmer Test Connector Universal w Cable Adapter | eBay) is 18x the price of what I ordered ;)

EDIT: and if you think I need to go with something more like what you suggested, is this (http://www.ebay.com/itm/1PC-CLIP-EEPROM-SOIC-14CON-for-Universal-5251-0714-NO-43-Brand-New-/151358463845?hash=item233daadf65&item=151358463845&pt=Motors_Automotive_Tools&vxp=mtr) or this (http://www.ebay.com/itm/SOIC8-SOP8-...665?pt=LH_DefaultDomain_0&hash=item4ad8439d01) the same thing? (It comes to $7 for me, instead of $24)
 

Attachments

  • revised 2.png
    revised 2.png
    18.7 KB · Views: 139
Last edited:
The second clip in your edit is the same as I suggest. These let you reprogram the chip AFTER reflow, which is rather important sometimes. In this case you will want to adjust the TriggerCount variable as this is the timebase for how long the button has to be held down to register.

The order of the two functions in your first two quotes isn't a bad change efficiency wise, good catch. The first writes the value as 9 to memory (if it was 9) and then resets the live variable to 1. This means that the next run through the loop would overwrite the 9 in memory as 1. The second way resets it to one and writes that to memory, resulting in no overwrite the next cycle. That would reduce EEPROM wear.

I thought you wanted the random state to rapidly change color randomly, my mistake. If you want it to sit on a random color we have to do it a bit differently. The problem is that the random function is only pseudo-random, so it will yield the same result EVERY power up. You can't put it into the void setup() function as a result. It stops being random. Let me know a truly random function is important to you and I'll write a true random function that uses time as the seed and only runs once per button press. It may not fit on the chip's memory though, those types of subroutines tend to be hungry.

As for getting it to sit on a value. We can set the random number generation to be done in the button threshold loop, and that should work.
Here's a revision:

Code:
// RHD's TTL Color Selector
// Programming by Matt "Sigurthr" Giordano 08/13/2014
// www.SigurthrEnterprises.com
// Sigurthr@SigurthrEnterprises.com

// ATTiny85 Physical Pinout - innermost designation is code addressable
//                   _______
// Reset           _|  |_|  |_   Vcc
// ADC3 Pin3   3   _|       |_ 2 Pin2 ADC1
// ADC2 Pin4  A2   _| ATT85 |_ 1 Pin1 Digital-1
// Gnd             _|       |_ 0 Pin0 Digital-0
//                  |_______|
  

#include <EEPROM.h> // include the EEPROM Memory library

int PressDetects = 0;
int ButtonPin = 3; // see pinout
int ColorOnePin = 0; // see pinout
int ColorTwoPin = 1; // see pinout
int ColorThreePin = 2; // see pinout
int MemVar;
int ButtonPinState;
int ColorChoice;
int MemoryLocation = 1;
unsigned int TriggerCount = 10; // threshold for debounce

void setup (){ // this subroutine runs once upon startup
  MemVar = EEPROM.read(MemoryLocation); // read EEPROM on power on
  pinMode (0, OUTPUT); // set pin 0 to output
  pinMode (1, OUTPUT); // set pin 1 to output
  pinMode (2, OUTPUT); // set pin 2 to output
  pinMode (3, INPUT); // set pin 3 to input
}

void loop(){ // this subroutine runs continuously after setup finishes
  ButtonPinState = digitalRead(ButtonPin);  // read ButtonPin to ButtonPinState  
  if (MemVar == 0 || 255){  // first time an EEPROM is read it reads as 255
    MemVar = 1;
  }
  if (ButtonPinState == HIGH){ // when ButtonPinState is HIGH...
    ++ PressDetects; // increment detection variable
  }
  if (PressDetects >= TriggerCount) { // when threshold is exceeded...
    ++ MemVar; // increment memory variable
    PressDetects = 0; // reset button detector
    if (MemVar >= 9){ // on 9th button press...
      MemVar = 1; // reset color
    }  
    if (MemVar == 8){ // on 8th button press...
      ColorChoice = random(1, 7);
    }  
    EEPROM.write(MemoryLocation, MemVar); // write color to memory       
  }
  if (MemVar != 8){ // prevents ColorChoice from being set to 8 (invalid)
    ColorChoice = MemVar;
  }  
  if (ColorChoice == 1){
    digitalWrite(ColorOnePin, HIGH);
    digitalWrite(ColorTwoPin, HIGH);
    digitalWrite(ColorThreePin, HIGH);
  }
  if (ColorChoice == 2){
    digitalWrite(ColorOnePin, HIGH);
    digitalWrite(ColorTwoPin, LOW);
    digitalWrite(ColorThreePin, LOW);
  }
  if (ColorChoice == 3){
    digitalWrite(ColorOnePin, HIGH);
    digitalWrite(ColorTwoPin, HIGH);
    digitalWrite(ColorThreePin, LOW);
  }  
  if (ColorChoice == 4){
    digitalWrite(ColorOnePin, LOW);
    digitalWrite(ColorTwoPin, HIGH);
    digitalWrite(ColorThreePin, LOW);
  }
  if (ColorChoice == 5){
    digitalWrite(ColorOnePin, LOW);
    digitalWrite(ColorTwoPin, HIGH);
    digitalWrite(ColorThreePin, HIGH);
  }
  if (ColorChoice == 6){
    digitalWrite(ColorOnePin, LOW);
    digitalWrite(ColorTwoPin, LOW);
    digitalWrite(ColorThreePin, HIGH);
  }
  if (ColorChoice == 7){
    digitalWrite(ColorOnePin, HIGH);
    digitalWrite(ColorTwoPin, LOW);
    digitalWrite(ColorThreePin, HIGH);
  }
}

Schematic looks good btw. I'll PM you my address. I'll include my paypal address in there too in case you feel like donating at all, totally up to you. =)
 
Last edited:
You could cut the program size if you change all the unnecessary integers to bytes. The EEPROM can only have single bytes written to it at a time - you are writing an integer, which is fine, but once it's value goes over 255 it'll simply max out at that, it doesn't automatically spread to the next EEPROM address.

EEPROM cycles are write only, reading does not have limited cycles.

Compiles to a bit under 1.4kb:

Code:
// RHD's TTL Color Selector
// Programming by Matt "Sigurthr" Giordano 08/13/2014
// www.SigurthrEnterprises.com
// Sigurthr@SigurthrEnterprises.com

// ATTiny85 Physical Pinout - innermost designation is code addressable
//                   _______
// Reset           _|  |_|  |_   Vcc
// ADC3 Pin3   3   _|       |_ 2 Pin2 ADC1
// ADC2 Pin4  A2   _| ATT85 |_ 1 Pin1 Digital-1
// Gnd             _|       |_ 0 Pin0 Digital-0
//                  |_______|
  

#include <EEPROM.h> // include the EEPROM Memory library

byte PressDetects = 0;
byte ButtonPin = 3; // see pinout
byte ColorOnePin = 0; // see pinout
byte ColorTwoPin = 1; // see pinout
byte ColorThreePin = 2; // see pinout
byte MemVar;
byte ButtonPinState;
byte ColorChoice;
byte MemoryLocation = 1;
int TriggerCount = 10; // threshold for debounce

void setup (){ // this subroutine runs once upon startup
  MemVar = EEPROM.read(MemoryLocation); // read EEPROM on power on
  pinMode (0, OUTPUT); // set pin 0 to output
  pinMode (1, OUTPUT); // set pin 1 to output
  pinMode (2, OUTPUT); // set pin 2 to output
  pinMode (3, INPUT); // set pin 3 to input
}

void loop(){ // this subroutine runs continuously after setup finishes
  ButtonPinState = digitalRead(ButtonPin);  // read ButtonPin to ButtonPinState  
  if (MemVar == 0 || 255){  // first time an EEPROM is read it reads as 255
    MemVar = 1;
  }
  if (ButtonPinState == HIGH){ // when ButtonPinState is HIGH...
    ++ PressDetects; // increment detection variable
  }
  if (PressDetects >= TriggerCount) { // when threshold is exceeded...
    ++ MemVar; // increment memory variable
    PressDetects = 0; // reset button detector
    if (MemVar >= 9){ // on 9th button press...
      MemVar = 1; // reset color
    }  
    if (MemVar == 8){ // on 8th button press...
      ColorChoice = random(1, 7);
    }  
    EEPROM.write(MemoryLocation, MemVar); // write color to memory       
  }

  switch (ColorChoice) {
  case 1:
    digitalWrite(ColorOnePin, HIGH);
    digitalWrite(ColorTwoPin, HIGH);
    digitalWrite(ColorThreePin, HIGH);
  break;
  
  case 2:
    digitalWrite(ColorOnePin, HIGH);
    digitalWrite(ColorTwoPin, LOW);
    digitalWrite(ColorThreePin, LOW);
  break;
    
  case 3:
    digitalWrite(ColorOnePin, HIGH);
    digitalWrite(ColorTwoPin, HIGH);
    digitalWrite(ColorThreePin, LOW);
  break;
  
  case 4:
    digitalWrite(ColorOnePin, LOW);
    digitalWrite(ColorTwoPin, HIGH);
    digitalWrite(ColorThreePin, LOW);
  break;
  
  case 5:
    digitalWrite(ColorOnePin, LOW);
    digitalWrite(ColorTwoPin, HIGH);
    digitalWrite(ColorThreePin, HIGH);
  break;
  
  case 6:
    digitalWrite(ColorOnePin, LOW);
    digitalWrite(ColorTwoPin, LOW);
    digitalWrite(ColorThreePin, HIGH);
  break;
  
  case 7:
    digitalWrite(ColorOnePin, HIGH);
    digitalWrite(ColorTwoPin, LOW);
    digitalWrite(ColorThreePin, HIGH);
  break;
  
  default:
    ColorChoice = MemVar;
  break;
  }
}

I left triggercount as an int, but realistically if it's never gonna be above 255 then it could be a byte too.

I also converted a bunch of the if statements to a switch, which also took off another few bytes :)
 
Last edited:
Thanks, Things!

The 85 has plenty of memory for the above program, it's only if I write a true RNG that I'd worry about space.

Good to know about the EEPROM only storing a single byte. I was wondering about that. We're only seeing values 1-9 so it shouldn't be an issue for this application.

Do you know if the value has to change to "consume" an EEPROM cycle?
 
AFAIK the stock library always re-writes it anyway.

Got it down to 1.3kb here, don't think you could really go any less except shaving off some variables and hard-coding them:

Code:
// RHD's TTL Color Selector
// Programming by Matt "Sigurthr" Giordano 08/13/2014
// www.SigurthrEnterprises.com
// Sigurthr@SigurthrEnterprises.com

// ATTiny85 Physical Pinout - innermost designation is code addressable
//                   _______
// Reset           _|  |_|  |_   Vcc
// ADC3 Pin3   3   _|       |_ 2 Pin2 ADC1
// ADC2 Pin4  A2   _| ATT85 |_ 1 Pin1 Digital-1
// Gnd             _|       |_ 0 Pin0 Digital-0
//                  |_______|
  

#include <EEPROM.h> // include the EEPROM Memory library
boolean pinOptions[7][3] = { // Array of pin combinations (1 = on, 0 = off)
  {1,1,1},
  {1,0,0},
  {1,1,0},
  {0,1,0},
  {0,1,1},
  {0,0,1},
  {1,0,1}
};

byte PressDetects = 0;
byte ButtonPin = 3; // see pinout
byte ColorOnePin = 0; // see pinout
byte ColorTwoPin = 1; // see pinout
byte ColorThreePin = 2; // see pinout
byte MemVar;
byte ButtonPinState;
byte ColorChoice;
byte MemoryLocation = 1;
byte TriggerCount = 10; // threshold for debounce

void setup (){ // this subroutine runs once upon startup
  MemVar = EEPROM.read(MemoryLocation); // read EEPROM on power on
  pinMode (0, OUTPUT); // set pin 0 to output
  pinMode (1, OUTPUT); // set pin 1 to output
  pinMode (2, OUTPUT); // set pin 2 to output
  pinMode (3, INPUT); // set pin 3 to input
}

void loop(){ // this subroutine runs continuously after setup finishes
  ButtonPinState = digitalRead(ButtonPin);  // read ButtonPin to ButtonPinState  
  if (MemVar == 0 || 255){  // first time an EEPROM is read it reads as 255
    MemVar = 1;
  }
  if (ButtonPinState == HIGH){ // when ButtonPinState is HIGH...
    ++ PressDetects; // increment detection variable
  }
  if (PressDetects >= TriggerCount) { // when threshold is exceeded...
    ++ MemVar; // increment memory variable
    PressDetects = 0; // reset button detector
    if (MemVar >= 9){ // on 9th button press...
      MemVar = 1; // reset color
    }  
    if (MemVar == 8){ // on 8th button press...
      ColorChoice = random(1, 7);
    }  
    EEPROM.write(MemoryLocation, MemVar); // write color to memory       
  }
    if (MemVar != 8){ // prevents ColorChoice from being set to 8 (invalid)
    ColorChoice = MemVar;
  }  
  digitalWrite(ColorOnePin, pinOptions[ColorChoice-1][0]);
  digitalWrite(ColorTwoPin, pinOptions[ColorChoice-1][1]);
  digitalWrite(ColorThreePin, pinOptions[ColorChoice-1][2]);
}
 
Last edited:
That pinOptions function is intriguing, is it part of the standard library? I haven't seen it before!
 
It's just a 2 dimensional array, really useful when you have a whole bunch of different pins you want to toggle :)

Just realized though that since the array is 0 indexed, you'd probably have to add a "spacer" array before the first one since ColorChoice is always >0. Or just subtract one. Have updated the previous code.

I also changed the pinOptions array to boolean .. though for whatever stupid reason they still occupy 1 byte in Arduino, even though they can only be 0 or 1, 1 bit. The code probably would fit on the tiny13 if that was the case :(
 
Last edited:





Back
Top