Last active
March 20, 2020 06:56
-
-
Save mattrude/4fd6fbb814cd7c07e1558050f1e4c7a3 to your computer and use it in GitHub Desktop.
ATtiny85, 74HC959 Traffic Light program written for Atmel Studio 7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* ATtiny85 - Advanced Traffic Stop Light - Version 0.1.1 - 2020-03-20 | |
* Copyright (c) 2020 Matt Rude <[email protected]> | |
* | |
* ********************************************************************************* | |
* | |
* This is the Advanced Traffic Stop Light program written for an ATtiny85 using | |
* Atmel Studio 7: https://www.microchip.com/mplab/avr-support/atmel-studio-7 | |
* | |
* For more on the ATtiny85, see: https://www.microchip.com/wwwproducts/en/ATtiny85 | |
* | |
* The ATtiny85 was programed with the Tiny AVR programmer PGM-11801 by SparkFun | |
* Electronics: https://www.sparkfun.com/products/11801 | |
* | |
* The circuit is powered by an external DC buck converter running at +5v. | |
* | |
* ********************************************************************************* | |
* | |
* Required Hardware: | |
* | |
* - 1x ATtiny85 Micro Controller | |
* - 1x 74HC959 Shift Register | |
* - 2x Red LED | |
* - 2x Yellow LED | |
* - 2x Green LED | |
* - 6x 220 ohm Resistors | |
* - 1x Large Breadboard | |
* - 20x Jumper Wires of various colors | |
* | |
* Required Tools: | |
* | |
* - Generic Windows 7+ Computer with a free USB port | |
* - Atmel Studio 7 software | |
* - Tiny AVR programmer - PGM-11801 | |
* - DC Power Supply | |
* | |
* ********************************************************************************* | |
* | |
* ATtiny85 pin-out: | |
* (Note: the dot next to the PB5 pin represents the dot on the chip.) | |
* ______ | |
* PB5 - |° | - VCC - 5v+ | |
* PB3 - | | - PB2 - To DS on 74HC595 | |
* PB4 - | | - PB1 - To STCP on 74HC595 | |
* GND - GND - |______| - PB0 - To SHCP on 74HC595 | |
* | |
* 74HC959 Shift Register pin-out: | |
* (Note: the dot next to the Q1 pin represents the dot on the chip.) | |
* ______ | |
* Red1 - Q1 - |° | - VCC - +5v | |
* Yellow1 - Q2 - | | - Q0 | |
* Green1 - Q3 - | | - DS - To PB2 on ATtiny85 | |
* Red2 - Q4 - | | - OE - GND | |
* Yellow2 - Q5 - | | - STCP - To PB1 on ATtiny85 | |
* Green2 - Q6 - | | - SHCP - To PB0 on ATtiny85 | |
* Q7 - | | - MR - +5v | |
* GND - GND - |______| - Q7S | |
* | |
* ********************************************************************************* | |
* | |
* Changelog: | |
* | |
* 2020-03-20 - 0.1.1 - Correct WDT function to load at start correctly. | |
* Minor comment updates | |
* 2020-03-07 - 0.1.0 - Initial Release | |
* | |
* ********************************************************************************* | |
* | |
* MIT License | |
* | |
* Copyright (c) 2020 Matt Rude <[email protected]> | |
* | |
* Permission is hereby granted, free of charge, to any person obtaining a copy | |
* of this software and associated documentation files (the "Software"), to deal | |
* in the Software without restriction, including without limitation the rights | |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
* copies of the Software, and to permit persons to whom the Software is | |
* furnished to do so, subject to the following conditions: | |
* | |
* The above copyright notice and this permission notice shall be included in all | |
* copies or substantial portions of the Software. | |
* | |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
* SOFTWARE. | |
* | |
* ********************************************************************************* | |
*/ | |
// Set the default amount of time, in seconds, to wait between light changes. | |
#define changeDelay 30 // Delay light changes in Seconds | |
// Declare the shift register pins | |
#define clockPin PB0 // Connected to SHCP (pin 11) on the 74HC595. | |
#define latchPin PB1 // Connected to STCP (pin 12) on the 74HC595. | |
#define dataPin PB2 // Connected to DS (pin 14) on the 74HC595. | |
// Set required variables | |
#define F_CPU 1000000UL // Set the CPU clock frequency to 1MHz | |
// Include the required libraries for the program | |
#include <util/delay.h> // Include the Delay library | |
#include <avr/io.h> // Include the IO library | |
#include <avr/wdt.h> // Include the WatchDog library | |
// Declare the micros | |
#define WDTO_2S 7 // Set the watch dog timer to about 2 seconds | |
#define MCUCSR MCUSR // Source of why an issue happened | |
#define setHigh(pn) PORTB |= (1<<pn) // Write digital HIGH to pin <pn> on PORTB | |
#define setLow(pn) PORTB &= ~(1<<pn) // Write digital LOW to pin <pn> on PORTB | |
// Declare the functions | |
void safeMode(uint8_t); // Run safe mode error function | |
void feedDog(); // Reset the watchdog timer | |
void delay(uint8_t); // Delay function | |
void send(uint8_t); // Send a Byte to the Shift Register | |
void sendBit(uint8_t); // Send a Bit to the Shift Register | |
void latch(); // Latch the Shift Register | |
void cycleClock(); // Cycle the Shift Register clock | |
// Now that everything is setup, starting the main process | |
int main(void) { | |
// Check to see if the last ran was finished correctly | |
if(MCUCSR & (1<<EXTRF)) { | |
safeMode(10); // External reset! | |
} else if(MCUCSR & (1<<BORF )) { | |
safeMode(20); // Brownout reset! | |
} else if(MCUCSR & (1<<WDRF )) { | |
safeMode(50); // Watchdog reset! | |
} | |
// Set the three shift register pins as outputs | |
DDRB |= (1 << clockPin) | (1 << latchPin) | (1 << dataPin); | |
// Before we begin, set the clockPin to LOW | |
PORTB &= ~(1<<clockPin); | |
// The primary loop | |
while (1) { | |
// Set BOTH directions to Red | |
send(0b00111111); | |
delay(changeDelay/8); | |
// Set the first directions to Green and the second to Red | |
send(0b10000010); | |
delay(changeDelay); | |
// Set the first directions to Yellow and keep the second direction Red | |
send(0b01000010); | |
delay(changeDelay/2); | |
// Set the Both directions to Red | |
send(0b00100010); | |
delay(changeDelay/8); | |
// Set the first directions to Red and the second to Green | |
send(0b00101000); | |
delay(changeDelay); | |
// Set the first directions to Yellow and keep the second direction Red | |
send(0b00100100); | |
delay(changeDelay/2); | |
} // Closing the primary loop | |
} // Closing the main process | |
// The error function | |
void safeMode(uint8_t errorReason) { | |
send(0b00100010); | |
delay(10); | |
errorReason = ((errorReason)*10); | |
uint8_t i; | |
for (i = 0; i < errorReason; i++) { | |
send(0b00100000); | |
delay(1); | |
send(0b00000010); | |
delay(1); | |
} | |
} // Closing the safeMode function | |
// Delay and feed the dog all at the same time | |
void delay(uint8_t delayTime) { | |
while (delayTime >= 0) { | |
feedDog(); | |
_delay_ms(1000); | |
delayTime = (delayTime-1); | |
} | |
feedDog(); | |
} // Closing the delay function | |
// Reset the watch dog timer | |
void feedDog() { | |
#define wdt_reset( ) __asm__ __volatile__ ("wdr") | |
} // Closing the feedDog function | |
// Writes a byte out to the dataPin | |
void send(uint8_t toSend) { | |
uint8_t i; | |
for (i = 0; i < 8; i++) { | |
sendBit(toSend & 1); | |
toSend >>= 1; | |
} | |
latch(); // Once the Byte has been written, cycle the latch pin to output the data | |
feedDog(); // Reset the watch dog timer | |
} // Closing the send function | |
// Writes a single bit to the dataPin, then cycles the clock | |
void sendBit(uint8_t bit) { | |
if (bit == 0) { | |
setLow(dataPin); | |
} else { | |
setHigh(dataPin); | |
} | |
cycleClock(); // Once the bit has been written, cycle the clock | |
} // Closing the sendBit function | |
// Tells the shift register to output all the bits it has | |
void latch() { | |
setHigh(latchPin); | |
setLow(latchPin); | |
} // Closing the latch function | |
// Tells the shift register to read a bit by ticking the clock forward | |
void cycleClock() { | |
setHigh(clockPin); | |
setLow(clockPin); | |
} // Closing the cycleClock function |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment