DCF77-Analyzer-Clock-v2
BIN
Arduino Libraries/DS1307RTC.zip
Normal file
BIN
Arduino Libraries/OneWire.zip
Normal file
BIN
Arduino Libraries/Time.zip
Normal file
@@ -0,0 +1,353 @@
|
|||||||
|
//
|
||||||
|
// This is the Superfilter sketch I use with the DCF Analyzer/Clock 2.0
|
||||||
|
// Udo Klein did an amazing job with this filter
|
||||||
|
//
|
||||||
|
// Erik de Ruiter
|
||||||
|
|
||||||
|
/*
|
||||||
|
Arduino Uno pin connections I used for the DCF Analyzer Clock
|
||||||
|
|
||||||
|
DCF input ................. A5 (19) = dcf77_sample_pin
|
||||||
|
Output DCF Filtered ....... 12 = dcf77_filtered_pin
|
||||||
|
Output DCF Semi Synthesized A2 (16) = dcf77_semi_synthesized_pin
|
||||||
|
Output DCF Synthesized .... 6 = dcf77_synthesized_pin
|
||||||
|
LED DCF output filtered ... A4 (18) = dcf77_monitor_pin = DCF Monitor LED
|
||||||
|
LED 1 Hz pulse ............ 10 = dcf77_second_pulse_pin = Filter Locked LED
|
||||||
|
LED DCF OK ................ 13 = dcf77_signal_good_indicator_pin = Signal Quality LED
|
||||||
|
LED Difference Filtered ... 7 = dcf77_filter_diff_pin \
|
||||||
|
LED Difference Semi Synth.. A0 = dcf77_semi_synthesized_diff_pin -> = Signal Difference LED
|
||||||
|
LED Difference Synthesized 4 = dcf77_synthesized_diff_pin /
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// www.blinkenlight.net
|
||||||
|
//
|
||||||
|
// Copyright 2014, 2015 Udo Klein
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
|
#include <dcf77.h>
|
||||||
|
/*
|
||||||
|
const uint8_t pon_pin = 51; // connect pon to ground !!!
|
||||||
|
const uint8_t data_pin = 19;
|
||||||
|
const uint8_t gnd_pin = 51;
|
||||||
|
const uint8_t vcc_pin = 49;
|
||||||
|
*/
|
||||||
|
|
||||||
|
const uint8_t dcf77_analog_samples = false;
|
||||||
|
const uint8_t dcf77_analog_sample_pin = 5;
|
||||||
|
const uint8_t dcf77_sample_pin = 19; // A5
|
||||||
|
const uint8_t dcf77_inverted_samples = 0;
|
||||||
|
#if defined(__AVR__)
|
||||||
|
#define ledpin(led) (led)
|
||||||
|
#else
|
||||||
|
#define ledpin(led) (led<14? led: led+(54-14))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const uint8_t dcf77_monitor_pin = ledpin(18); // A4
|
||||||
|
|
||||||
|
const bool provide_filtered_output = true;
|
||||||
|
const uint8_t dcf77_filtered_pin = ledpin(12);
|
||||||
|
const uint8_t dcf77_inverted_filtered_pin = ledpin(11);
|
||||||
|
const uint8_t dcf77_filter_diff_pin = ledpin(7);
|
||||||
|
|
||||||
|
const bool provide_semi_synthesized_output = true;
|
||||||
|
const uint8_t dcf77_semi_synthesized_pin = ledpin(16);
|
||||||
|
const uint8_t dcf77_inverted_semi_synthesized_pin = ledpin(15);
|
||||||
|
const uint8_t dcf77_semi_synthesized_diff_pin = ledpin(14);
|
||||||
|
|
||||||
|
const bool provide_synthesized_output = true;
|
||||||
|
const uint8_t dcf77_synthesized_pin = ledpin(6);
|
||||||
|
const uint8_t dcf77_inverted_synthesized_pin = ledpin(5);
|
||||||
|
const uint8_t dcf77_synthesized_diff_pin = ledpin(4);
|
||||||
|
|
||||||
|
const uint8_t dcf77_second_pulse_pin = ledpin(10);
|
||||||
|
|
||||||
|
|
||||||
|
const uint8_t dcf77_signal_good_indicator_pin = ledpin(13);
|
||||||
|
|
||||||
|
volatile uint16_t ms_counter = 0;
|
||||||
|
volatile Internal::DCF77::tick_t tick = Internal::DCF77::undefined;
|
||||||
|
|
||||||
|
|
||||||
|
template <bool enable, uint8_t threshold,
|
||||||
|
uint8_t filtered_pin, uint8_t inverted_filtered_pin, uint8_t diff_pin>
|
||||||
|
void set_output(uint8_t clock_state, uint8_t sampled_data, uint8_t synthesized_signal)
|
||||||
|
{
|
||||||
|
if (enable) {
|
||||||
|
const uint8_t filtered_output = clock_state < threshold? sampled_data: synthesized_signal;
|
||||||
|
digitalWrite(filtered_pin, filtered_output);
|
||||||
|
digitalWrite(inverted_filtered_pin, !filtered_output);
|
||||||
|
digitalWrite(diff_pin, filtered_output ^ sampled_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
struct Scope {
|
||||||
|
static const uint16_t samples_per_second = 1000;
|
||||||
|
static const uint8_t bins = 100;
|
||||||
|
static const uint8_t samples_per_bin = samples_per_second / bins;
|
||||||
|
|
||||||
|
volatile uint8_t gbin[bins];
|
||||||
|
volatile boolean samples_pending = false;
|
||||||
|
volatile uint32_t count = 0;
|
||||||
|
|
||||||
|
void process_one_sample(const uint8_t sample) {
|
||||||
|
static uint8_t sbin[bins];
|
||||||
|
|
||||||
|
static uint16_t ticks = 999; // first pass will init the bins
|
||||||
|
++ticks;
|
||||||
|
|
||||||
|
if (ticks == 1000) {
|
||||||
|
ticks = 0;
|
||||||
|
memcpy((void *)gbin, sbin, bins);
|
||||||
|
memset(sbin, 0, bins);
|
||||||
|
samples_pending = true;
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
sbin[ticks/samples_per_bin] += sample;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print() {
|
||||||
|
uint8_t lbin[bins];
|
||||||
|
|
||||||
|
if (samples_pending) {
|
||||||
|
noInterrupts();
|
||||||
|
memcpy(lbin, (void *)gbin, bins);
|
||||||
|
samples_pending = false;
|
||||||
|
interrupts();
|
||||||
|
|
||||||
|
// ensure the count values will be aligned to the right
|
||||||
|
for (int32_t val=count; val < 100000000; val *= 10) {
|
||||||
|
Serial.print(' ');
|
||||||
|
}
|
||||||
|
Serial.print((int32_t)count);
|
||||||
|
Serial.print(", ");
|
||||||
|
for (uint8_t bin=0; bin<bins; ++bin) {
|
||||||
|
switch (lbin[bin]) {
|
||||||
|
case 0: Serial.print(bin%10? '-': '+'); break;
|
||||||
|
case 10: Serial.print('X'); break;
|
||||||
|
default: Serial.print(lbin[bin]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Scope scope_1;
|
||||||
|
Scope scope_2;
|
||||||
|
|
||||||
|
uint8_t sample_input_pin() {
|
||||||
|
const uint8_t clock_state = DCF77_Clock::get_clock_state();
|
||||||
|
const uint8_t sampled_data =
|
||||||
|
#if defined(__AVR__)
|
||||||
|
dcf77_inverted_samples ^ (dcf77_analog_samples? (analogRead(dcf77_analog_sample_pin) > 200)
|
||||||
|
: digitalRead(dcf77_sample_pin));
|
||||||
|
#else
|
||||||
|
dcf77_inverted_samples ^ digitalRead(dcf77_sample_pin);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
digitalWrite(dcf77_monitor_pin, sampled_data);
|
||||||
|
digitalWrite(dcf77_second_pulse_pin, ms_counter < 500 && clock_state >= Clock::locked);
|
||||||
|
|
||||||
|
const uint8_t synthesized_signal =
|
||||||
|
tick == Internal::DCF77::long_tick ? ms_counter < 200:
|
||||||
|
tick == Internal::DCF77::short_tick ? ms_counter < 100:
|
||||||
|
tick == Internal::DCF77::sync_mark ? 0:
|
||||||
|
// tick == DCF77::undefined --> default handling
|
||||||
|
// allow signal to pass for the first 200ms of each second
|
||||||
|
(ms_counter <=200 && sampled_data) ||
|
||||||
|
// if the clock has valid time data then undefined ticks
|
||||||
|
// are data bits --> first 100ms of signal must be high
|
||||||
|
ms_counter <100;
|
||||||
|
|
||||||
|
set_output<provide_filtered_output, Clock::locked,
|
||||||
|
dcf77_filtered_pin, dcf77_inverted_filtered_pin, dcf77_filter_diff_pin>
|
||||||
|
(clock_state, sampled_data, synthesized_signal);
|
||||||
|
|
||||||
|
set_output<provide_semi_synthesized_output, Clock::unlocked,
|
||||||
|
dcf77_semi_synthesized_pin, dcf77_inverted_semi_synthesized_pin, dcf77_semi_synthesized_diff_pin>
|
||||||
|
(clock_state, sampled_data, synthesized_signal);
|
||||||
|
|
||||||
|
set_output<provide_synthesized_output, Clock::free,
|
||||||
|
dcf77_synthesized_pin, dcf77_inverted_synthesized_pin, dcf77_synthesized_diff_pin>
|
||||||
|
(clock_state, sampled_data, synthesized_signal);
|
||||||
|
|
||||||
|
ms_counter+= (ms_counter < 1000);
|
||||||
|
|
||||||
|
scope_1.process_one_sample(sampled_data);
|
||||||
|
scope_2.process_one_sample(digitalRead(dcf77_synthesized_pin));
|
||||||
|
|
||||||
|
return sampled_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void output_handler(const Clock::time_t &decoded_time) {
|
||||||
|
// reset ms_counter for 1 Hz ticks
|
||||||
|
ms_counter = 0;
|
||||||
|
|
||||||
|
// status indicator --> always on if signal is good
|
||||||
|
// blink 3s on 1s off if signal is poor
|
||||||
|
// blink 1s on 3s off if signal is very poor
|
||||||
|
// always off if signal is bad
|
||||||
|
const uint8_t clock_state = DCF77_Clock::get_clock_state();
|
||||||
|
digitalWrite(dcf77_signal_good_indicator_pin,
|
||||||
|
clock_state >= Clock::locked ? 1:
|
||||||
|
clock_state == Clock::unlocked? (decoded_time.second.digit.lo & 0x03) != 0:
|
||||||
|
clock_state == Clock::free ? (decoded_time.second.digit.lo & 0x03) == 0:
|
||||||
|
0);
|
||||||
|
// compute output for signal synthesis
|
||||||
|
Internal::DCF77_Encoder now;
|
||||||
|
now.second = BCD::bcd_to_int(decoded_time.second);
|
||||||
|
now.minute = decoded_time.minute;
|
||||||
|
now.hour = decoded_time.hour;
|
||||||
|
now.weekday = decoded_time.weekday;
|
||||||
|
now.day = decoded_time.day;
|
||||||
|
now.month = decoded_time.month;
|
||||||
|
now.year = decoded_time.year;
|
||||||
|
now.uses_summertime = decoded_time.uses_summertime;
|
||||||
|
now.leap_second_scheduled = decoded_time.leap_second_scheduled;
|
||||||
|
now.timezone_change_scheduled = decoded_time.timezone_change_scheduled;
|
||||||
|
|
||||||
|
now.undefined_minute_output = false;
|
||||||
|
now.undefined_uses_summertime_output = false;
|
||||||
|
now.undefined_abnormal_transmitter_operation_output = false;
|
||||||
|
now.undefined_timezone_change_scheduled_output = false;
|
||||||
|
|
||||||
|
now.advance_minute();
|
||||||
|
tick = now.get_current_signal();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup_serial() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
}
|
||||||
|
|
||||||
|
void output_splash_screen() {
|
||||||
|
Serial.println();
|
||||||
|
Serial.println(F("DCF77 Superfilter 3.0"));
|
||||||
|
Serial.println(F("(c) 2015 Udo Klein"));
|
||||||
|
Serial.println(F("www.blinkenlight.net"));
|
||||||
|
Serial.println();
|
||||||
|
Serial.print(F("Sample Pin: ")); Serial.println(dcf77_sample_pin);
|
||||||
|
Serial.print(F("Inverted Mode: ")); Serial.println(dcf77_inverted_samples);
|
||||||
|
#if defined(__AVR__)
|
||||||
|
Serial.print(F("Analog Mode: ")); Serial.println(dcf77_analog_samples);
|
||||||
|
#endif
|
||||||
|
Serial.print(F("Monitor Pin: ")); Serial.println(dcf77_monitor_pin);
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
if (provide_filtered_output) {
|
||||||
|
Serial.println(F("Filtered Output"));
|
||||||
|
Serial.print(F(" Filtered Pin: ")); Serial.println(dcf77_filtered_pin);
|
||||||
|
Serial.print(F(" Diff Pin: ")); Serial.println(dcf77_filter_diff_pin);
|
||||||
|
Serial.print(F(" Inverse Filtered Pin: ")); Serial.println(dcf77_inverted_filtered_pin);
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (provide_semi_synthesized_output) {
|
||||||
|
Serial.println(F("Semi Synthesized Output"));
|
||||||
|
Serial.print(F(" Filtered Pin: ")); Serial.println(dcf77_semi_synthesized_pin);
|
||||||
|
Serial.print(F(" Diff Pin: ")); Serial.println(dcf77_semi_synthesized_diff_pin);
|
||||||
|
Serial.print(F(" Inverse Filtered Pin: ")); Serial.println(dcf77_inverted_semi_synthesized_pin);
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (provide_synthesized_output) {
|
||||||
|
Serial.println(F("Synthesized Output"));
|
||||||
|
Serial.print(F(" Filtered Pin: ")); Serial.println(dcf77_synthesized_pin);
|
||||||
|
Serial.print(F(" Diff Pin: ")); Serial.println(dcf77_synthesized_diff_pin);
|
||||||
|
Serial.print(F(" Inverse Filtered Pin: ")); Serial.println(dcf77_inverted_synthesized_pin);
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.print(F("Second Pulse Pin: ")); Serial.println(dcf77_second_pulse_pin);
|
||||||
|
Serial.print(F("Signal Good Pin: ")); Serial.println(dcf77_signal_good_indicator_pin);
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
Serial.println(F("Initializing..."));
|
||||||
|
Serial.println();
|
||||||
|
};
|
||||||
|
|
||||||
|
void setup_pins() {
|
||||||
|
if (provide_filtered_output) {
|
||||||
|
pinMode(dcf77_filtered_pin, OUTPUT);
|
||||||
|
pinMode(dcf77_filter_diff_pin, OUTPUT);
|
||||||
|
pinMode(dcf77_inverted_filtered_pin, OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (provide_semi_synthesized_output) {
|
||||||
|
pinMode(dcf77_semi_synthesized_pin, OUTPUT);
|
||||||
|
pinMode(dcf77_semi_synthesized_diff_pin, OUTPUT);
|
||||||
|
pinMode(dcf77_inverted_semi_synthesized_pin, OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (provide_synthesized_output) {
|
||||||
|
pinMode(dcf77_synthesized_pin, OUTPUT);
|
||||||
|
pinMode(dcf77_synthesized_diff_pin, OUTPUT);
|
||||||
|
pinMode(dcf77_inverted_synthesized_pin, OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
pinMode(dcf77_monitor_pin, OUTPUT);
|
||||||
|
pinMode(dcf77_signal_good_indicator_pin, OUTPUT);
|
||||||
|
pinMode(dcf77_second_pulse_pin, OUTPUT);
|
||||||
|
pinMode(dcf77_sample_pin, INPUT);
|
||||||
|
digitalWrite(dcf77_sample_pin, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup_clock() {
|
||||||
|
DCF77_Clock::setup();
|
||||||
|
DCF77_Clock::set_input_provider(sample_input_pin);
|
||||||
|
DCF77_Clock::set_output_handler(output_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
setup_serial();
|
||||||
|
output_splash_screen();
|
||||||
|
setup_pins();
|
||||||
|
setup_clock();
|
||||||
|
/*
|
||||||
|
pinMode(gnd_pin, OUTPUT);
|
||||||
|
digitalWrite(gnd_pin, LOW);
|
||||||
|
pinMode(pon_pin, OUTPUT);
|
||||||
|
digitalWrite(pon_pin, LOW);
|
||||||
|
pinMode(vcc_pin, OUTPUT);
|
||||||
|
digitalWrite(vcc_pin, HIGH);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
Clock::time_t now;
|
||||||
|
DCF77_Clock::get_current_time(now);
|
||||||
|
|
||||||
|
if (now.month.val > 0) {
|
||||||
|
Serial.println();
|
||||||
|
Serial.print(F("Decoded time: "));
|
||||||
|
|
||||||
|
DCF77_Clock::print(now);
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.print(DCF77_Clock::get_clock_state());
|
||||||
|
Serial.print(' ');
|
||||||
|
DCF77_Clock::debug();
|
||||||
|
|
||||||
|
scope_1.print();
|
||||||
|
scope_2.print();
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 9.2 MiB |
|
Before Width: | Height: | Size: 2.6 MiB |
BIN
DCF77_Analyzer_Clock_v2_BackPanel_Preview.png
Normal file
|
After Width: | Height: | Size: 123 KiB |
BIN
DCF77_Analyzer_Clock_v2_FrontPanel_Preview.jpg
Normal file
|
After Width: | Height: | Size: 375 KiB |
BIN
DCF77_clock.jpg
|
Before Width: | Height: | Size: 309 KiB |
|
After Width: | Height: | Size: 538 KiB |
|
After Width: | Height: | Size: 8.8 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
BIN
Grandfather_Clock_Sound_files/T00.ogg
Executable file
BIN
Grandfather_Clock_Sound_files/T10HOLDL.ogg
Executable file
@@ -1,213 +0,0 @@
|
|||||||
/*
|
|
||||||
* LedControl.cpp - A library for controling Leds with a MAX7219/MAX7221
|
|
||||||
* Copyright (c) 2007 Eberhard Fahle
|
|
||||||
*
|
|
||||||
* 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:
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "LedControl.h"
|
|
||||||
|
|
||||||
//the opcodes for the MAX7221 and MAX7219
|
|
||||||
#define OP_NOOP 0
|
|
||||||
#define OP_DIGIT0 1
|
|
||||||
#define OP_DIGIT1 2
|
|
||||||
#define OP_DIGIT2 3
|
|
||||||
#define OP_DIGIT3 4
|
|
||||||
#define OP_DIGIT4 5
|
|
||||||
#define OP_DIGIT5 6
|
|
||||||
#define OP_DIGIT6 7
|
|
||||||
#define OP_DIGIT7 8
|
|
||||||
#define OP_DECODEMODE 9
|
|
||||||
#define OP_INTENSITY 10
|
|
||||||
#define OP_SCANLIMIT 11
|
|
||||||
#define OP_SHUTDOWN 12
|
|
||||||
#define OP_DISPLAYTEST 15
|
|
||||||
|
|
||||||
LedControl::LedControl(int dataPin, int clkPin, int csPin, int numDevices) {
|
|
||||||
SPI_MOSI=dataPin;
|
|
||||||
SPI_CLK=clkPin;
|
|
||||||
SPI_CS=csPin;
|
|
||||||
if(numDevices<=0 || numDevices>8 )
|
|
||||||
numDevices=8;
|
|
||||||
maxDevices=numDevices;
|
|
||||||
pinMode(SPI_MOSI,OUTPUT);
|
|
||||||
pinMode(SPI_CLK,OUTPUT);
|
|
||||||
pinMode(SPI_CS,OUTPUT);
|
|
||||||
digitalWrite(SPI_CS,HIGH);
|
|
||||||
SPI_MOSI=dataPin;
|
|
||||||
for(int i=0;i<64;i++)
|
|
||||||
status[i]=0x00;
|
|
||||||
for(int i=0;i<maxDevices;i++) {
|
|
||||||
spiTransfer(i,OP_DISPLAYTEST,0);
|
|
||||||
//scanlimit is set to max on startup
|
|
||||||
setScanLimit(i,7);
|
|
||||||
//decode is done in source
|
|
||||||
spiTransfer(i,OP_DECODEMODE,0);
|
|
||||||
clearDisplay(i);
|
|
||||||
//we go into shutdown-mode on startup
|
|
||||||
shutdown(i,true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int LedControl::getDeviceCount() {
|
|
||||||
return maxDevices;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::shutdown(int addr, bool b) {
|
|
||||||
if(addr<0 || addr>=maxDevices)
|
|
||||||
return;
|
|
||||||
if(b)
|
|
||||||
spiTransfer(addr, OP_SHUTDOWN,0);
|
|
||||||
else
|
|
||||||
spiTransfer(addr, OP_SHUTDOWN,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::setScanLimit(int addr, int limit) {
|
|
||||||
if(addr<0 || addr>=maxDevices)
|
|
||||||
return;
|
|
||||||
if(limit>=0 || limit<8)
|
|
||||||
spiTransfer(addr, OP_SCANLIMIT,limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::setIntensity(int addr, int intensity) {
|
|
||||||
if(addr<0 || addr>=maxDevices)
|
|
||||||
return;
|
|
||||||
if(intensity>=0 || intensity<16)
|
|
||||||
spiTransfer(addr, OP_INTENSITY,intensity);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::clearDisplay(int addr) {
|
|
||||||
int offset;
|
|
||||||
|
|
||||||
if(addr<0 || addr>=maxDevices)
|
|
||||||
return;
|
|
||||||
offset=addr*8;
|
|
||||||
for(int i=0;i<8;i++) {
|
|
||||||
status[offset+i]=0;
|
|
||||||
spiTransfer(addr, i+1,status[offset+i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::setLed(int addr, int row, int column, boolean state) {
|
|
||||||
int offset;
|
|
||||||
byte val=0x00;
|
|
||||||
|
|
||||||
if(addr<0 || addr>=maxDevices)
|
|
||||||
return;
|
|
||||||
if(row<0 || row>7 || column<0 || column>7)
|
|
||||||
return;
|
|
||||||
offset=addr*8;
|
|
||||||
val=B10000000 >> column;
|
|
||||||
if(state)
|
|
||||||
status[offset+row]=status[offset+row]|val;
|
|
||||||
else {
|
|
||||||
val=~val;
|
|
||||||
status[offset+row]=status[offset+row]&val;
|
|
||||||
}
|
|
||||||
spiTransfer(addr, row+1,status[offset+row]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::setRow(int addr, int row, byte value) {
|
|
||||||
int offset;
|
|
||||||
if(addr<0 || addr>=maxDevices)
|
|
||||||
return;
|
|
||||||
if(row<0 || row>7)
|
|
||||||
return;
|
|
||||||
offset=addr*8;
|
|
||||||
status[offset+row]=value;
|
|
||||||
spiTransfer(addr, row+1,status[offset+row]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::setColumn(int addr, int col, byte value) {
|
|
||||||
byte val;
|
|
||||||
|
|
||||||
if(addr<0 || addr>=maxDevices)
|
|
||||||
return;
|
|
||||||
if(col<0 || col>7)
|
|
||||||
return;
|
|
||||||
for(int row=0;row<8;row++) {
|
|
||||||
val=value >> (7-row);
|
|
||||||
val=val & 0x01;
|
|
||||||
setLed(addr,row,col,val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::setDigit(int addr, int digit, byte value, boolean dp) {
|
|
||||||
int offset;
|
|
||||||
byte v;
|
|
||||||
|
|
||||||
if(addr<0 || addr>=maxDevices)
|
|
||||||
return;
|
|
||||||
if(digit<0 || digit>7 || value>15)
|
|
||||||
return;
|
|
||||||
offset=addr*8;
|
|
||||||
v=charTable[value];
|
|
||||||
if(dp)
|
|
||||||
v|=B10000000;
|
|
||||||
status[offset+digit]=v;
|
|
||||||
spiTransfer(addr, digit+1,v);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::setChar(int addr, int digit, char value, boolean dp) {
|
|
||||||
int offset;
|
|
||||||
byte index,v;
|
|
||||||
|
|
||||||
if(addr<0 || addr>=maxDevices)
|
|
||||||
return;
|
|
||||||
if(digit<0 || digit>7)
|
|
||||||
return;
|
|
||||||
offset=addr*8;
|
|
||||||
index=(byte)value;
|
|
||||||
if(index >127) {
|
|
||||||
//nothing define we use the space char
|
|
||||||
value=32;
|
|
||||||
}
|
|
||||||
v=charTable[index];
|
|
||||||
if(dp)
|
|
||||||
v|=B10000000;
|
|
||||||
status[offset+digit]=v;
|
|
||||||
spiTransfer(addr, digit+1,v);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::spiTransfer(int addr, volatile byte opcode, volatile byte data) {
|
|
||||||
//Create an array with the data to shift out
|
|
||||||
int offset=addr*2;
|
|
||||||
int maxbytes=maxDevices*2;
|
|
||||||
|
|
||||||
for(int i=0;i<maxbytes;i++)
|
|
||||||
spidata[i]=(byte)0;
|
|
||||||
//put our device data into the array
|
|
||||||
spidata[offset+1]=opcode;
|
|
||||||
spidata[offset]=data;
|
|
||||||
//enable the line
|
|
||||||
digitalWrite(SPI_CS,LOW);
|
|
||||||
//Now shift out the data
|
|
||||||
for(int i=maxbytes;i>0;i--)
|
|
||||||
shiftOut(SPI_MOSI,SPI_CLK,MSBFIRST,spidata[i-1]);
|
|
||||||
//latch the data onto the display
|
|
||||||
digitalWrite(SPI_CS,HIGH);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,188 +0,0 @@
|
|||||||
/*
|
|
||||||
* LedControl.h - A library for controling Leds with a MAX7219/MAX7221
|
|
||||||
* Copyright (c) 2007 Eberhard Fahle
|
|
||||||
*
|
|
||||||
* 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:
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LedControl_h
|
|
||||||
#define LedControl_h
|
|
||||||
|
|
||||||
#if (ARDUINO >= 100)
|
|
||||||
#include <Arduino.h>
|
|
||||||
#else
|
|
||||||
#include <WProgram.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Segments to be switched on for characters and digits on
|
|
||||||
* 7-Segment Displays
|
|
||||||
*/
|
|
||||||
const static byte charTable[128] = {
|
|
||||||
B01111110,B00110000,B01101101,B01111001,B00110011,B01011011,B01011111,B01110000,
|
|
||||||
B01111111,B01111011,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111,
|
|
||||||
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
|
|
||||||
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
|
|
||||||
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
|
|
||||||
B00000000,B00000000,B00000000,B00000000,B10000000,B00000001,B10000000,B00000000,
|
|
||||||
B01111110,B00110000,B01101101,B01111001,B00110011,B01011011,B01011111,B01110000,
|
|
||||||
B01111111,B01111011,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
|
|
||||||
B00000000,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111,B00000000,
|
|
||||||
B00110111,B00000000,B00000000,B00000000,B00001110,B00000000,B00000000,B00000000,
|
|
||||||
B01100111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
|
|
||||||
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001000,
|
|
||||||
B00000000,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111,B00000000,
|
|
||||||
B00110111,B00000000,B00000000,B00000000,B00001110,B00000000,B00000000,B00000000,
|
|
||||||
B01100111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
|
|
||||||
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000
|
|
||||||
};
|
|
||||||
|
|
||||||
class LedControl {
|
|
||||||
private :
|
|
||||||
/* The array for shifting the data to the devices */
|
|
||||||
byte spidata[16];
|
|
||||||
/* Send out a single command to the device */
|
|
||||||
void spiTransfer(int addr, byte opcode, byte data);
|
|
||||||
|
|
||||||
/* We keep track of the led-status for all 8 devices in this array */
|
|
||||||
byte status[64];
|
|
||||||
/* Data is shifted out of this pin*/
|
|
||||||
int SPI_MOSI;
|
|
||||||
/* The clock is signaled on this pin */
|
|
||||||
int SPI_CLK;
|
|
||||||
/* This one is driven LOW for chip selectzion */
|
|
||||||
int SPI_CS;
|
|
||||||
/* The maximum number of devices we use */
|
|
||||||
int maxDevices;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/*
|
|
||||||
* Create a new controler
|
|
||||||
* Params :
|
|
||||||
* dataPin pin on the Arduino where data gets shifted out
|
|
||||||
* clockPin pin for the clock
|
|
||||||
* csPin pin for selecting the device
|
|
||||||
* numDevices maximum number of devices that can be controled
|
|
||||||
*/
|
|
||||||
LedControl(int dataPin, int clkPin, int csPin, int numDevices=1);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Gets the number of devices attached to this LedControl.
|
|
||||||
* Returns :
|
|
||||||
* int the number of devices on this LedControl
|
|
||||||
*/
|
|
||||||
int getDeviceCount();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the shutdown (power saving) mode for the device
|
|
||||||
* Params :
|
|
||||||
* addr The address of the display to control
|
|
||||||
* status If true the device goes into power-down mode. Set to false
|
|
||||||
* for normal operation.
|
|
||||||
*/
|
|
||||||
void shutdown(int addr, bool status);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the number of digits (or rows) to be displayed.
|
|
||||||
* See datasheet for sideeffects of the scanlimit on the brightness
|
|
||||||
* of the display.
|
|
||||||
* Params :
|
|
||||||
* addr address of the display to control
|
|
||||||
* limit number of digits to be displayed (1..8)
|
|
||||||
*/
|
|
||||||
void setScanLimit(int addr, int limit);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the brightness of the display.
|
|
||||||
* Params:
|
|
||||||
* addr the address of the display to control
|
|
||||||
* intensity the brightness of the display. (0..15)
|
|
||||||
*/
|
|
||||||
void setIntensity(int addr, int intensity);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Switch all Leds on the display off.
|
|
||||||
* Params:
|
|
||||||
* addr address of the display to control
|
|
||||||
*/
|
|
||||||
void clearDisplay(int addr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the status of a single Led.
|
|
||||||
* Params :
|
|
||||||
* addr address of the display
|
|
||||||
* row the row of the Led (0..7)
|
|
||||||
* col the column of the Led (0..7)
|
|
||||||
* state If true the led is switched on,
|
|
||||||
* if false it is switched off
|
|
||||||
*/
|
|
||||||
void setLed(int addr, int row, int col, boolean state);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set all 8 Led's in a row to a new state
|
|
||||||
* Params:
|
|
||||||
* addr address of the display
|
|
||||||
* row row which is to be set (0..7)
|
|
||||||
* value each bit set to 1 will light up the
|
|
||||||
* corresponding Led.
|
|
||||||
*/
|
|
||||||
void setRow(int addr, int row, byte value);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set all 8 Led's in a column to a new state
|
|
||||||
* Params:
|
|
||||||
* addr address of the display
|
|
||||||
* col column which is to be set (0..7)
|
|
||||||
* value each bit set to 1 will light up the
|
|
||||||
* corresponding Led.
|
|
||||||
*/
|
|
||||||
void setColumn(int addr, int col, byte value);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Display a hexadecimal digit on a 7-Segment Display
|
|
||||||
* Params:
|
|
||||||
* addr address of the display
|
|
||||||
* digit the position of the digit on the display (0..7)
|
|
||||||
* value the value to be displayed. (0x00..0x0F)
|
|
||||||
* dp sets the decimal point.
|
|
||||||
*/
|
|
||||||
void setDigit(int addr, int digit, byte value, boolean dp);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Display a character on a 7-Segment display.
|
|
||||||
* There are only a few characters that make sense here :
|
|
||||||
* '0','1','2','3','4','5','6','7','8','9','0',
|
|
||||||
* 'A','b','c','d','E','F','H','L','P',
|
|
||||||
* '.','-','_',' '
|
|
||||||
* Params:
|
|
||||||
* addr address of the display
|
|
||||||
* digit the position of the character on the display (0..7)
|
|
||||||
* value the character to be displayed.
|
|
||||||
* dp sets the decimal point.
|
|
||||||
*/
|
|
||||||
void setChar(int addr, int digit, char value, boolean dp);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //LedControl.h
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,310 +0,0 @@
|
|||||||
/*
|
|
||||||
* LedControl.cpp - A library for controling Leds with a MAX7219/MAX7221
|
|
||||||
* Copyright (c) 2007 Eberhard Fahle
|
|
||||||
*
|
|
||||||
* 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:
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "LedControl.h"
|
|
||||||
|
|
||||||
//the opcodes for the MAX7221 and MAX7219
|
|
||||||
#define OP_NOOP 0
|
|
||||||
#define OP_DIGIT0 1
|
|
||||||
#define OP_DIGIT1 2
|
|
||||||
#define OP_DIGIT2 3
|
|
||||||
#define OP_DIGIT3 4
|
|
||||||
#define OP_DIGIT4 5
|
|
||||||
#define OP_DIGIT5 6
|
|
||||||
#define OP_DIGIT6 7
|
|
||||||
#define OP_DIGIT7 8
|
|
||||||
#define OP_DECODEMODE 9
|
|
||||||
#define OP_INTENSITY 10
|
|
||||||
#define OP_SCANLIMIT 11
|
|
||||||
#define OP_SHUTDOWN 12
|
|
||||||
#define OP_DISPLAYTEST 15
|
|
||||||
|
|
||||||
LedControl::LedControl(int dataPin, int clkPin, int csPin, int numDevices, bool anode) {
|
|
||||||
SPI_MOSI=dataPin;
|
|
||||||
SPI_CLK=clkPin;
|
|
||||||
SPI_CS=csPin;
|
|
||||||
if(numDevices<=0 || numDevices>8 )
|
|
||||||
numDevices=8;
|
|
||||||
maxDevices=numDevices;
|
|
||||||
anodeMode=anode;
|
|
||||||
pinMode(SPI_MOSI,OUTPUT);
|
|
||||||
pinMode(SPI_CLK,OUTPUT);
|
|
||||||
pinMode(SPI_CS,OUTPUT);
|
|
||||||
digitalWrite(SPI_CS,HIGH);
|
|
||||||
SPI_MOSI=dataPin;
|
|
||||||
for(int i=0;i<64;i++) {
|
|
||||||
status[i]=0x00;
|
|
||||||
statusTransposed[i]=0x00;
|
|
||||||
}
|
|
||||||
for(int i=0;i<maxDevices;i++) {
|
|
||||||
spiTransfer(i,OP_DISPLAYTEST,0);
|
|
||||||
//scanlimit is set to max on startup
|
|
||||||
setScanLimit(i,7);
|
|
||||||
//decode is done in source
|
|
||||||
spiTransfer(i,OP_DECODEMODE,0);
|
|
||||||
clearDisplay(i);
|
|
||||||
//we go into shutdown-mode on startup
|
|
||||||
shutdown(i,true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int LedControl::getDeviceCount() {
|
|
||||||
return maxDevices;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::shutdown(int addr, bool b) {
|
|
||||||
if(addr<0 || addr>=maxDevices)
|
|
||||||
return;
|
|
||||||
if(b)
|
|
||||||
spiTransfer(addr, OP_SHUTDOWN,0);
|
|
||||||
else
|
|
||||||
spiTransfer(addr, OP_SHUTDOWN,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::setScanLimit(int addr, int limit) {
|
|
||||||
if(addr<0 || addr>=maxDevices)
|
|
||||||
return;
|
|
||||||
if(limit>=0 || limit<8)
|
|
||||||
spiTransfer(addr, OP_SCANLIMIT,limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::setIntensity(int addr, int intensity) {
|
|
||||||
if(addr<0 || addr>=maxDevices)
|
|
||||||
return;
|
|
||||||
if(intensity>=0 || intensity<16)
|
|
||||||
spiTransfer(addr, OP_INTENSITY,intensity);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::clearDisplay(int addr) {
|
|
||||||
int offset;
|
|
||||||
|
|
||||||
if(addr<0 || addr>=maxDevices)
|
|
||||||
return;
|
|
||||||
offset=addr*8;
|
|
||||||
for(int i=0;i<8;i++) {
|
|
||||||
status[offset+i]=0;
|
|
||||||
}
|
|
||||||
if (anodeMode) {
|
|
||||||
transposeData(addr);
|
|
||||||
for(int i=0;i<8;i++) {
|
|
||||||
spiTransfer(addr, i+1, statusTransposed[offset+i]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for(int i=0;i<8;i++) {
|
|
||||||
spiTransfer(addr, i+1, status[offset+i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::setLed(int addr, int row, int column, boolean state) {
|
|
||||||
int offset;
|
|
||||||
byte val=0x00;
|
|
||||||
|
|
||||||
if(addr<0 || addr>=maxDevices)
|
|
||||||
return;
|
|
||||||
if(row<0 || row>7 || column<0 || column>7)
|
|
||||||
return;
|
|
||||||
offset=addr*8;
|
|
||||||
val=B10000000 >> column;
|
|
||||||
if(state)
|
|
||||||
status[offset+row]=status[offset+row]|val;
|
|
||||||
else {
|
|
||||||
val=~val;
|
|
||||||
status[offset+row]=status[offset+row]&val;
|
|
||||||
}
|
|
||||||
spiTransfer(addr, row+1,status[offset+row]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::setRow(int addr, int row, byte value) {
|
|
||||||
int offset;
|
|
||||||
if(addr<0 || addr>=maxDevices)
|
|
||||||
return;
|
|
||||||
if(row<0 || row>7)
|
|
||||||
return;
|
|
||||||
offset=addr*8;
|
|
||||||
status[offset+row]=value;
|
|
||||||
spiTransfer(addr, row+1,status[offset+row]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::setColumn(int addr, int col, byte value) {
|
|
||||||
byte val;
|
|
||||||
|
|
||||||
if(addr<0 || addr>=maxDevices)
|
|
||||||
return;
|
|
||||||
if(col<0 || col>7)
|
|
||||||
return;
|
|
||||||
for(int row=0;row<8;row++) {
|
|
||||||
val=value >> (7-row);
|
|
||||||
val=val & 0x01;
|
|
||||||
setLed(addr,row,col,val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::setDigit(int addr, int digit, byte value, boolean dp) {
|
|
||||||
int offset;
|
|
||||||
byte v;
|
|
||||||
|
|
||||||
if(addr<0 || addr>=maxDevices)
|
|
||||||
return;
|
|
||||||
if(digit<0 || digit>7 || value>15)
|
|
||||||
return;
|
|
||||||
offset=addr*8;
|
|
||||||
v=charTable[value];
|
|
||||||
if(dp)
|
|
||||||
v|=B10000000;
|
|
||||||
status[offset+digit]=v;
|
|
||||||
if (anodeMode) {
|
|
||||||
//transpose the digit matrix
|
|
||||||
transposeData(addr);
|
|
||||||
//send the entire set of digits
|
|
||||||
for(int i=0;i<8;i++) {
|
|
||||||
spiTransfer(addr, i+1, statusTransposed[offset+i]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
spiTransfer(addr, digit+1, v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::setChar(int addr, int digit, char value, boolean dp) {
|
|
||||||
int offset;
|
|
||||||
byte index,v;
|
|
||||||
|
|
||||||
if(addr<0 || addr>=maxDevices)
|
|
||||||
return;
|
|
||||||
if(digit<0 || digit>7)
|
|
||||||
return;
|
|
||||||
|
|
||||||
offset=addr*8;
|
|
||||||
index=(byte)value;
|
|
||||||
if(index >127) {
|
|
||||||
//nothing defined we use the space char
|
|
||||||
value=32;
|
|
||||||
}
|
|
||||||
v=charTable[index];
|
|
||||||
if(dp)
|
|
||||||
v|=B10000000;
|
|
||||||
status[offset+digit]=v;
|
|
||||||
if (anodeMode) {
|
|
||||||
//transpose the digit matrix
|
|
||||||
transposeData(addr);
|
|
||||||
//send the entire set of digits
|
|
||||||
for(int i=0;i<8;i++) {
|
|
||||||
spiTransfer(addr, i+1, statusTransposed[offset+i]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
spiTransfer(addr, digit+1, v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::spiTransfer(int addr, volatile byte opcode, volatile byte data) {
|
|
||||||
//Create an array with the data to shift out
|
|
||||||
int offset=addr*2;
|
|
||||||
int maxbytes=maxDevices*2;
|
|
||||||
|
|
||||||
for(int i=0;i<maxbytes;i++)
|
|
||||||
spidata[i]=(byte)0;
|
|
||||||
//put our device data into the array
|
|
||||||
spidata[offset+1]=opcode;
|
|
||||||
spidata[offset]=data;
|
|
||||||
//enable the line
|
|
||||||
digitalWrite(SPI_CS,LOW);
|
|
||||||
//Now shift out the data
|
|
||||||
for(int i=maxbytes;i>0;i--)
|
|
||||||
shiftOut(SPI_MOSI,SPI_CLK,MSBFIRST,spidata[i-1]);
|
|
||||||
//latch the data onto the display
|
|
||||||
digitalWrite(SPI_CS,HIGH);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LedControl::transposeData(int addr) {
|
|
||||||
int offset=addr*8;
|
|
||||||
byte a0, a1, a2, a3, a4, a5, a6, a7,
|
|
||||||
b0, b1, b2, b3, b4, b5, b6, b7;
|
|
||||||
|
|
||||||
// Perform a bitwise transpose operation on an 8x8 bit matrix, stored as 8-byte array.
|
|
||||||
// We have to use the naive method because we're working on a 16-bit microprocessor.
|
|
||||||
|
|
||||||
// Load the array into eight one-byte variables.
|
|
||||||
a0 = status[offset];
|
|
||||||
a1 = status[offset+1];
|
|
||||||
a2 = status[offset+2];
|
|
||||||
a3 = status[offset+3];
|
|
||||||
a4 = status[offset+4];
|
|
||||||
a5 = status[offset+5];
|
|
||||||
a6 = status[offset+6];
|
|
||||||
a7 = status[offset+7];
|
|
||||||
|
|
||||||
// Magic happens. Credit goes to: http://www.hackersdelight.org/HDcode/transpose8.c.txt
|
|
||||||
b0 = (a0 & 128) | (a1 & 128)/2 | (a2 & 128)/4 | (a3 & 128)/8 |
|
|
||||||
(a4 & 128)/16 | (a5 & 128)/32 | (a6 & 128)/64 | (a7 )/128;
|
|
||||||
b1 = (a0 & 64)*2 | (a1 & 64) | (a2 & 64)/2 | (a3 & 64)/4 |
|
|
||||||
(a4 & 64)/8 | (a5 & 64)/16 | (a6 & 64)/32 | (a7 & 64)/64;
|
|
||||||
b2 = (a0 & 32)*4 | (a1 & 32)*2 | (a2 & 32) | (a3 & 32)/2 |
|
|
||||||
(a4 & 32)/4 | (a5 & 32)/8 | (a6 & 32)/16 | (a7 & 32)/32;
|
|
||||||
b3 = (a0 & 16)*8 | (a1 & 16)*4 | (a2 & 16)*2 | (a3 & 16) |
|
|
||||||
(a4 & 16)/2 | (a5 & 16)/4 | (a6 & 16)/8 | (a7 & 16)/16;
|
|
||||||
b4 = (a0 & 8)*16 | (a1 & 8)*8 | (a2 & 8)*4 | (a3 & 8)*2 |
|
|
||||||
(a4 & 8) | (a5 & 8)/2 | (a6 & 8)/4 | (a7 & 8)/8;
|
|
||||||
b5 = (a0 & 4)*32 | (a1 & 4)*16 | (a2 & 4)*8 | (a3 & 4)*4 |
|
|
||||||
(a4 & 4)*2 | (a5 & 4) | (a6 & 4)/2 | (a7 & 4)/4;
|
|
||||||
b6 = (a0 & 2)*64 | (a1 & 2)*32 | (a2 & 2)*16 | (a3 & 2)*8 |
|
|
||||||
(a4 & 2)*4 | (a5 & 2)*2 | (a6 & 2) | (a7 & 2)/2;
|
|
||||||
b7 = (a0 )*128| (a1 & 1)*64 | (a2 & 1)*32 | (a3 & 1)*16|
|
|
||||||
(a4 & 1)*8 | (a5 & 1)*4 | (a6 & 1)*2 | (a7 & 1);
|
|
||||||
|
|
||||||
// Assemble into output array.
|
|
||||||
statusTransposed[offset] = b0;
|
|
||||||
statusTransposed[offset+1] = b1;
|
|
||||||
statusTransposed[offset+2] = b2;
|
|
||||||
statusTransposed[offset+3] = b3;
|
|
||||||
statusTransposed[offset+4] = b4;
|
|
||||||
statusTransposed[offset+5] = b5;
|
|
||||||
statusTransposed[offset+6] = b6;
|
|
||||||
statusTransposed[offset+7] = b7;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::setDirectDigit(int addr, int digit, byte value) {
|
|
||||||
int offset;
|
|
||||||
|
|
||||||
if(addr<0 || addr>=maxDevices)
|
|
||||||
return;
|
|
||||||
if(digit<0 || digit>7)
|
|
||||||
return;
|
|
||||||
offset=addr*8;
|
|
||||||
status[offset+digit]=value;
|
|
||||||
if (anodeMode) {
|
|
||||||
transposeData(addr);
|
|
||||||
for(int i=0;i<8;i++) {
|
|
||||||
spiTransfer(addr, i+1, statusTransposed[offset+i]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
spiTransfer(addr, digit+1, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,217 +0,0 @@
|
|||||||
/*
|
|
||||||
* LedControl.h - A library for controling Leds with a MAX7219/MAX7221
|
|
||||||
* Copyright (c) 2007 Eberhard Fahle
|
|
||||||
*
|
|
||||||
* 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:
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LedControl_h
|
|
||||||
#define LedControl_h
|
|
||||||
|
|
||||||
#if (ARDUINO >= 100)
|
|
||||||
#include <Arduino.h>
|
|
||||||
#else
|
|
||||||
#include <WProgram.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Segments to be switched on for characters and digits on
|
|
||||||
* 7-Segment Displays
|
|
||||||
*/
|
|
||||||
const static byte charTable[128] = {
|
|
||||||
B01111110,B00110000,B01101101,B01111001,B00110011,B01011011,B01011111,B01110000,
|
|
||||||
B01111111,B01111011,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111,
|
|
||||||
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
|
|
||||||
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
|
|
||||||
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
|
|
||||||
B00000000,B00000000,B00000000,B00000000,B10000000,B00000001,B10000000,B00000000,
|
|
||||||
B01111110,B00110000,B01101101,B01111001,B00110011,B01011011,B01011111,B01110000,
|
|
||||||
B01111111,B01111011,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
|
|
||||||
B00000000,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111,B00000000,
|
|
||||||
B00110111,B00000000,B00000000,B00000000,B00001110,B00000000,B00000000,B00000000,
|
|
||||||
B01100111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
|
|
||||||
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001000,
|
|
||||||
B00000000,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111,B00000000,
|
|
||||||
B00110111,B00000000,B00000000,B00000000,B00001110,B00000000,B00000000,B00000000,
|
|
||||||
B01100111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
|
|
||||||
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000
|
|
||||||
};
|
|
||||||
|
|
||||||
class LedControl {
|
|
||||||
private :
|
|
||||||
/* The array for shifting the data to the devices */
|
|
||||||
byte spidata[16];
|
|
||||||
/* Send out a single command to the device */
|
|
||||||
void spiTransfer(int addr, byte opcode, byte data);
|
|
||||||
|
|
||||||
/* We keep track of the led-status for all 8 devices in this array */
|
|
||||||
byte status[64];
|
|
||||||
/* We also keep track of the transposed version */
|
|
||||||
byte statusTransposed[64];
|
|
||||||
/* Data is shifted out of this pin*/
|
|
||||||
int SPI_MOSI;
|
|
||||||
/* The clock is signaled on this pin */
|
|
||||||
int SPI_CLK;
|
|
||||||
/* This one is driven LOW for chip selectzion */
|
|
||||||
int SPI_CS;
|
|
||||||
/* The maximum number of devices we use */
|
|
||||||
int maxDevices;
|
|
||||||
/* Choose whether we're using common cathode or common anode displays */
|
|
||||||
bool anodeMode;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
/*
|
|
||||||
* Create a new controler
|
|
||||||
* Params :
|
|
||||||
* dataPin pin on the Arduino where data gets shifted out
|
|
||||||
* clockPin pin for the clock
|
|
||||||
* csPin pin for selecting the device
|
|
||||||
* numDevices maximum number of devices that can be controled
|
|
||||||
* anode false for common-cathode displays, true for common-anode displays
|
|
||||||
*/
|
|
||||||
LedControl(int dataPin, int clkPin, int csPin, int numDevices=1, bool anode=false);
|
|
||||||
/*
|
|
||||||
* Gets the number of devices attached to this LedControl.
|
|
||||||
* Returns :
|
|
||||||
* int the number of devices on this LedControl
|
|
||||||
*/
|
|
||||||
int getDeviceCount();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the shutdown (power saving) mode for the device
|
|
||||||
* Params :
|
|
||||||
* addr The address of the display to control
|
|
||||||
* status If true the device goes into power-down mode. Set to false
|
|
||||||
* for normal operation.
|
|
||||||
*/
|
|
||||||
void shutdown(int addr, bool status);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the number of digits (or rows) to be displayed.
|
|
||||||
* See datasheet for sideeffects of the scanlimit on the brightness
|
|
||||||
* of the display.
|
|
||||||
* Params :
|
|
||||||
* addr address of the display to control
|
|
||||||
* limit number of digits to be displayed (1..8)
|
|
||||||
*/
|
|
||||||
void setScanLimit(int addr, int limit);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the brightness of the display.
|
|
||||||
* Params:
|
|
||||||
* addr the address of the display to control
|
|
||||||
* intensity the brightness of the display. (0..15)
|
|
||||||
*/
|
|
||||||
void setIntensity(int addr, int intensity);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Switch all Leds on the display off.
|
|
||||||
* Params:
|
|
||||||
* addr address of the display to control
|
|
||||||
*/
|
|
||||||
void clearDisplay(int addr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the status of a single Led.
|
|
||||||
* Params :
|
|
||||||
* addr address of the display
|
|
||||||
* row the row of the Led (0..7)
|
|
||||||
* col the column of the Led (0..7)
|
|
||||||
* state If true the led is switched on,
|
|
||||||
* if false it is switched off
|
|
||||||
*/
|
|
||||||
void setLed(int addr, int row, int col, boolean state);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set all 8 Led's in a row to a new state
|
|
||||||
* Params:
|
|
||||||
* addr address of the display
|
|
||||||
* row row which is to be set (0..7)
|
|
||||||
* value each bit set to 1 will light up the
|
|
||||||
* corresponding Led.
|
|
||||||
*/
|
|
||||||
void setRow(int addr, int row, byte value);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set all 8 Led's in a column to a new state
|
|
||||||
* Params:
|
|
||||||
* addr address of the display
|
|
||||||
* col column which is to be set (0..7)
|
|
||||||
* value each bit set to 1 will light up the
|
|
||||||
* corresponding Led.
|
|
||||||
*/
|
|
||||||
void setColumn(int addr, int col, byte value);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Display a hexadecimal digit on a 7-Segment Display
|
|
||||||
* Params:
|
|
||||||
* addr address of the display
|
|
||||||
* digit the position of the digit on the display (0..7)
|
|
||||||
* value the value to be displayed. (0x00..0x0F)
|
|
||||||
* dp sets the decimal point.
|
|
||||||
*/
|
|
||||||
void setDigit(int addr, int digit, byte value, boolean dp);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Display a character on a 7-Segment display.
|
|
||||||
* There are only a few characters that make sense here :
|
|
||||||
* '0','1','2','3','4','5','6','7','8','9','0',
|
|
||||||
* 'A','b','c','d','E','F','H','L','P',
|
|
||||||
* '.','-','_',' '
|
|
||||||
* Params:
|
|
||||||
* addr address of the display
|
|
||||||
* digit the position of the character on the display (0..7)
|
|
||||||
* value the character to be displayed.
|
|
||||||
* dp sets the decimal point.
|
|
||||||
*/
|
|
||||||
void setChar(int addr, int digit, char value, boolean dp);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Transpose data matrix for use with common-anode displays.
|
|
||||||
* Params:
|
|
||||||
* addr address of the display
|
|
||||||
*/
|
|
||||||
void transposeData(int addr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Light up segments of a 7-segment display directly by passing a binary value.
|
|
||||||
* The eight bits of the byte each refer to a segment:
|
|
||||||
* Byte: 0 0 0 0 0 0 0 0
|
|
||||||
* Segments: DP A B C D E F G
|
|
||||||
* Params:
|
|
||||||
* addr address of the display
|
|
||||||
* digit the position of the character on the display (0..7)
|
|
||||||
* value the binary value to be displayed
|
|
||||||
*/
|
|
||||||
void setDirectDigit(int addr, int digit, byte value);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //LedControl.h
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,228 +0,0 @@
|
|||||||
Common subdirectories: LedControl-unpatched/examples and LedControl/examples
|
|
||||||
diff -u LedControl-unpatched/LedControl.cpp LedControl/LedControl.cpp
|
|
||||||
--- LedControl-unpatched/LedControl.cpp 2008-10-14 02:21:21.000000000 -0700
|
|
||||||
+++ LedControl/LedControl.cpp 2012-09-02 01:24:35.000000000 -0700
|
|
||||||
@@ -35,20 +35,23 @@
|
|
||||||
#define OP_SHUTDOWN 12
|
|
||||||
#define OP_DISPLAYTEST 15
|
|
||||||
|
|
||||||
-LedControl::LedControl(int dataPin, int clkPin, int csPin, int numDevices) {
|
|
||||||
+LedControl::LedControl(int dataPin, int clkPin, int csPin, int numDevices, bool anode) {
|
|
||||||
SPI_MOSI=dataPin;
|
|
||||||
SPI_CLK=clkPin;
|
|
||||||
SPI_CS=csPin;
|
|
||||||
if(numDevices<=0 || numDevices>8 )
|
|
||||||
numDevices=8;
|
|
||||||
maxDevices=numDevices;
|
|
||||||
+ anodeMode=anode;
|
|
||||||
pinMode(SPI_MOSI,OUTPUT);
|
|
||||||
pinMode(SPI_CLK,OUTPUT);
|
|
||||||
pinMode(SPI_CS,OUTPUT);
|
|
||||||
digitalWrite(SPI_CS,HIGH);
|
|
||||||
SPI_MOSI=dataPin;
|
|
||||||
- for(int i=0;i<64;i++)
|
|
||||||
+ for(int i=0;i<64;i++) {
|
|
||||||
status[i]=0x00;
|
|
||||||
+ statusTransposed[i]=0x00;
|
|
||||||
+ }
|
|
||||||
for(int i=0;i<maxDevices;i++) {
|
|
||||||
spiTransfer(i,OP_DISPLAYTEST,0);
|
|
||||||
//scanlimit is set to max on startup
|
|
||||||
@@ -97,7 +100,16 @@
|
|
||||||
offset=addr*8;
|
|
||||||
for(int i=0;i<8;i++) {
|
|
||||||
status[offset+i]=0;
|
|
||||||
- spiTransfer(addr, i+1,status[offset+i]);
|
|
||||||
+ }
|
|
||||||
+ if (anodeMode) {
|
|
||||||
+ transposeData(addr);
|
|
||||||
+ for(int i=0;i<8;i++) {
|
|
||||||
+ spiTransfer(addr, i+1, statusTransposed[offset+i]);
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ for(int i=0;i<8;i++) {
|
|
||||||
+ spiTransfer(addr, i+1, status[offset+i]);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -158,8 +170,16 @@
|
|
||||||
if(dp)
|
|
||||||
v|=B10000000;
|
|
||||||
status[offset+digit]=v;
|
|
||||||
- spiTransfer(addr, digit+1,v);
|
|
||||||
-
|
|
||||||
+ if (anodeMode) {
|
|
||||||
+ //transpose the digit matrix
|
|
||||||
+ transposeData(addr);
|
|
||||||
+ //send the entire set of digits
|
|
||||||
+ for(int i=0;i<8;i++) {
|
|
||||||
+ spiTransfer(addr, i+1, statusTransposed[offset+i]);
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ spiTransfer(addr, digit+1, v);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::setChar(int addr, int digit, char value, boolean dp) {
|
|
||||||
@@ -173,14 +193,23 @@
|
|
||||||
offset=addr*8;
|
|
||||||
index=(byte)value;
|
|
||||||
if(index >127) {
|
|
||||||
- //nothing define we use the space char
|
|
||||||
+ //nothing defined we use the space char
|
|
||||||
value=32;
|
|
||||||
}
|
|
||||||
v=charTable[index];
|
|
||||||
if(dp)
|
|
||||||
v|=B10000000;
|
|
||||||
status[offset+digit]=v;
|
|
||||||
- spiTransfer(addr, digit+1,v);
|
|
||||||
+ if (anodeMode) {
|
|
||||||
+ //transpose the digit matrix
|
|
||||||
+ transposeData(addr);
|
|
||||||
+ //send the entire set of digits
|
|
||||||
+ for(int i=0;i<8;i++) {
|
|
||||||
+ spiTransfer(addr, i+1, statusTransposed[offset+i]);
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ spiTransfer(addr, digit+1, v);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
void LedControl::spiTransfer(int addr, volatile byte opcode, volatile byte data) {
|
|
||||||
@@ -202,4 +231,73 @@
|
|
||||||
digitalWrite(SPI_CS,HIGH);
|
|
||||||
}
|
|
||||||
|
|
||||||
+void LedControl::transposeData(int addr) {
|
|
||||||
+ int offset=addr*8;
|
|
||||||
+ byte a0, a1, a2, a3, a4, a5, a6, a7,
|
|
||||||
+ b0, b1, b2, b3, b4, b5, b6, b7;
|
|
||||||
+
|
|
||||||
+ // Perform a bitwise transpose operation on an 8x8 bit matrix, stored as 8-byte array.
|
|
||||||
+ // We have to use the naive method because we're working on a 16-bit microprocessor.
|
|
||||||
+
|
|
||||||
+ // Load the array into eight one-byte variables.
|
|
||||||
+ a0 = status[offset];
|
|
||||||
+ a1 = status[offset+1];
|
|
||||||
+ a2 = status[offset+2];
|
|
||||||
+ a3 = status[offset+3];
|
|
||||||
+ a4 = status[offset+4];
|
|
||||||
+ a5 = status[offset+5];
|
|
||||||
+ a6 = status[offset+6];
|
|
||||||
+ a7 = status[offset+7];
|
|
||||||
+
|
|
||||||
+ // Magic happens. Credit goes to: http://www.hackersdelight.org/HDcode/transpose8.c.txt
|
|
||||||
+ b0 = (a0 & 128) | (a1 & 128)/2 | (a2 & 128)/4 | (a3 & 128)/8 |
|
|
||||||
+ (a4 & 128)/16 | (a5 & 128)/32 | (a6 & 128)/64 | (a7 )/128;
|
|
||||||
+ b1 = (a0 & 64)*2 | (a1 & 64) | (a2 & 64)/2 | (a3 & 64)/4 |
|
|
||||||
+ (a4 & 64)/8 | (a5 & 64)/16 | (a6 & 64)/32 | (a7 & 64)/64;
|
|
||||||
+ b2 = (a0 & 32)*4 | (a1 & 32)*2 | (a2 & 32) | (a3 & 32)/2 |
|
|
||||||
+ (a4 & 32)/4 | (a5 & 32)/8 | (a6 & 32)/16 | (a7 & 32)/32;
|
|
||||||
+ b3 = (a0 & 16)*8 | (a1 & 16)*4 | (a2 & 16)*2 | (a3 & 16) |
|
|
||||||
+ (a4 & 16)/2 | (a5 & 16)/4 | (a6 & 16)/8 | (a7 & 16)/16;
|
|
||||||
+ b4 = (a0 & 8)*16 | (a1 & 8)*8 | (a2 & 8)*4 | (a3 & 8)*2 |
|
|
||||||
+ (a4 & 8) | (a5 & 8)/2 | (a6 & 8)/4 | (a7 & 8)/8;
|
|
||||||
+ b5 = (a0 & 4)*32 | (a1 & 4)*16 | (a2 & 4)*8 | (a3 & 4)*4 |
|
|
||||||
+ (a4 & 4)*2 | (a5 & 4) | (a6 & 4)/2 | (a7 & 4)/4;
|
|
||||||
+ b6 = (a0 & 2)*64 | (a1 & 2)*32 | (a2 & 2)*16 | (a3 & 2)*8 |
|
|
||||||
+ (a4 & 2)*4 | (a5 & 2)*2 | (a6 & 2) | (a7 & 2)/2;
|
|
||||||
+ b7 = (a0 )*128| (a1 & 1)*64 | (a2 & 1)*32 | (a3 & 1)*16|
|
|
||||||
+ (a4 & 1)*8 | (a5 & 1)*4 | (a6 & 1)*2 | (a7 & 1);
|
|
||||||
+
|
|
||||||
+ // Assemble into output array.
|
|
||||||
+ statusTransposed[offset] = b0;
|
|
||||||
+ statusTransposed[offset+1] = b1;
|
|
||||||
+ statusTransposed[offset+2] = b2;
|
|
||||||
+ statusTransposed[offset+3] = b3;
|
|
||||||
+ statusTransposed[offset+4] = b4;
|
|
||||||
+ statusTransposed[offset+5] = b5;
|
|
||||||
+ statusTransposed[offset+6] = b6;
|
|
||||||
+ statusTransposed[offset+7] = b7;
|
|
||||||
+
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void LedControl::setDirectDigit(int addr, int digit, byte value) {
|
|
||||||
+ int offset;
|
|
||||||
+
|
|
||||||
+ if(addr<0 || addr>=maxDevices)
|
|
||||||
+ return;
|
|
||||||
+ if(digit<0 || digit>7)
|
|
||||||
+ return;
|
|
||||||
+ offset=addr*8;
|
|
||||||
+ status[offset+digit]=value;
|
|
||||||
+ if (anodeMode) {
|
|
||||||
+ transposeData(addr);
|
|
||||||
+ for(int i=0;i<8;i++) {
|
|
||||||
+ spiTransfer(addr, i+1, statusTransposed[offset+i]);
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ spiTransfer(addr, digit+1, value);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+
|
|
||||||
|
|
||||||
diff -u LedControl-unpatched/LedControl.h LedControl/LedControl.h
|
|
||||||
--- LedControl-unpatched/LedControl.h 2011-09-20 23:49:06.000000000 -0700
|
|
||||||
+++ LedControl/LedControl.h 2012-09-02 00:18:47.000000000 -0700
|
|
||||||
@@ -58,6 +58,8 @@
|
|
||||||
|
|
||||||
/* We keep track of the led-status for all 8 devices in this array */
|
|
||||||
byte status[64];
|
|
||||||
+ /* We also keep track of the transposed version */
|
|
||||||
+ byte statusTransposed[64];
|
|
||||||
/* Data is shifted out of this pin*/
|
|
||||||
int SPI_MOSI;
|
|
||||||
/* The clock is signaled on this pin */
|
|
||||||
@@ -66,6 +68,8 @@
|
|
||||||
int SPI_CS;
|
|
||||||
/* The maximum number of devices we use */
|
|
||||||
int maxDevices;
|
|
||||||
+ /* Choose whether we're using common cathode or common anode displays */
|
|
||||||
+ bool anodeMode;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/*
|
|
||||||
@@ -75,8 +79,9 @@
|
|
||||||
* clockPin pin for the clock
|
|
||||||
* csPin pin for selecting the device
|
|
||||||
* numDevices maximum number of devices that can be controled
|
|
||||||
+ * anode false for common-cathode displays, true for common-anode displays
|
|
||||||
*/
|
|
||||||
- LedControl(int dataPin, int clkPin, int csPin, int numDevices=1);
|
|
||||||
+ LedControl(int dataPin, int clkPin, int csPin, int numDevices=1, bool anode=false);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Gets the number of devices attached to this LedControl.
|
|
||||||
@@ -173,9 +178,25 @@
|
|
||||||
* dp sets the decimal point.
|
|
||||||
*/
|
|
||||||
void setChar(int addr, int digit, char value, boolean dp);
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Transpose data matrix for use with common-anode displays.
|
|
||||||
+ * Params:
|
|
||||||
+ * addr address of the display
|
|
||||||
+ */
|
|
||||||
+ void transposeData(int addr);
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Light up segments of a 7-segment display directly by passing a binary value.
|
|
||||||
+ * The eight bits of the byte each refer to a segment:
|
|
||||||
+ * Byte: 0 0 0 0 0 0 0 0
|
|
||||||
+ * Segments: DP A B C D E F G
|
|
||||||
+ * Params:
|
|
||||||
+ * addr address of the display
|
|
||||||
+ * digit the position of the character on the display (0..7)
|
|
||||||
+ * value the binary value to be displayed
|
|
||||||
+ */
|
|
||||||
+ void setDirectDigit(int addr, int digit, byte value);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //LedControl.h
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
//We always have to include the library
|
|
||||||
#include "LedControl.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
Now we need a LedControl to work with.
|
|
||||||
***** These pin numbers will probably not work with your hardware *****
|
|
||||||
pin 12 is connected to the DataIn
|
|
||||||
pin 11 is connected to the CLK
|
|
||||||
pin 10 is connected to LOAD
|
|
||||||
We have only a single MAX72XX.
|
|
||||||
*/
|
|
||||||
LedControl lc=LedControl(12,11,10,1);
|
|
||||||
|
|
||||||
/* we always wait a bit between updates of the display */
|
|
||||||
unsigned long delaytime=250;
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
/*
|
|
||||||
The MAX72XX is in power-saving mode on startup,
|
|
||||||
we have to do a wakeup call
|
|
||||||
*/
|
|
||||||
lc.shutdown(0,false);
|
|
||||||
/* Set the brightness to a medium values */
|
|
||||||
lc.setIntensity(0,8);
|
|
||||||
/* and clear the display */
|
|
||||||
lc.clearDisplay(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
This method will display the characters for the
|
|
||||||
word "Arduino" one after the other on digit 0.
|
|
||||||
*/
|
|
||||||
void writeArduinoOn7Segment() {
|
|
||||||
lc.setChar(0,0,'a',false);
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setRow(0,0,0x05);
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setChar(0,0,'d',false);
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setRow(0,0,0x1c);
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setRow(0,0,B00010000);
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setRow(0,0,0x15);
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setRow(0,0,0x1D);
|
|
||||||
delay(delaytime);
|
|
||||||
lc.clearDisplay(0);
|
|
||||||
delay(delaytime);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
This method will scroll all the hexa-decimal
|
|
||||||
numbers and letters on the display. You will need at least
|
|
||||||
four 7-Segment digits. otherwise it won't really look that good.
|
|
||||||
*/
|
|
||||||
void scrollDigits() {
|
|
||||||
for(int i=0;i<13;i++) {
|
|
||||||
lc.setDigit(0,3,i,false);
|
|
||||||
lc.setDigit(0,2,i+1,false);
|
|
||||||
lc.setDigit(0,1,i+2,false);
|
|
||||||
lc.setDigit(0,0,i+3,false);
|
|
||||||
delay(delaytime);
|
|
||||||
}
|
|
||||||
lc.clearDisplay(0);
|
|
||||||
delay(delaytime);
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
writeArduinoOn7Segment();
|
|
||||||
scrollDigits();
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
//We always have to include the library
|
|
||||||
#include "LedControl.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
Now we need a LedControl to work with.
|
|
||||||
***** These pin numbers will probably not work with your hardware *****
|
|
||||||
pin 12 is connected to the DataIn
|
|
||||||
pin 11 is connected to the CLK
|
|
||||||
pin 10 is connected to LOAD
|
|
||||||
***** Please set the number of devices you have *****
|
|
||||||
But the maximum default of 8 MAX72XX wil also work.
|
|
||||||
*/
|
|
||||||
LedControl lc=LedControl(12,11,10,8);
|
|
||||||
|
|
||||||
/* we always wait a bit between updates of the display */
|
|
||||||
unsigned long delaytime=500;
|
|
||||||
|
|
||||||
/*
|
|
||||||
This time we have more than one device.
|
|
||||||
But all of them have to be initialized
|
|
||||||
individually.
|
|
||||||
*/
|
|
||||||
void setup() {
|
|
||||||
//we have already set the number of devices when we created the LedControl
|
|
||||||
int devices=lc.getDeviceCount();
|
|
||||||
//we have to init all devices in a loop
|
|
||||||
for(int address=0;address<devices;address++) {
|
|
||||||
/*The MAX72XX is in power-saving mode on startup*/
|
|
||||||
lc.shutdown(address,false);
|
|
||||||
/* Set the brightness to a medium values */
|
|
||||||
lc.setIntensity(address,8);
|
|
||||||
/* and clear the display */
|
|
||||||
lc.clearDisplay(address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
//read the number cascaded devices
|
|
||||||
int devices=lc.getDeviceCount();
|
|
||||||
|
|
||||||
//we have to init all devices in a loop
|
|
||||||
for(int row=0;row<8;row++) {
|
|
||||||
for(int col=0;col<8;col++) {
|
|
||||||
for(int address=0;address<devices;address++) {
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setLed(address,row,col,true);
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setLed(address,row,col,false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,163 +0,0 @@
|
|||||||
//We always have to include the library
|
|
||||||
#include "LedControl.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
Now we need a LedControl to work with.
|
|
||||||
***** These pin numbers will probably not work with your hardware *****
|
|
||||||
pin 12 is connected to the DataIn
|
|
||||||
pin 11 is connected to the CLK
|
|
||||||
pin 10 is connected to LOAD
|
|
||||||
We have only a single MAX72XX.
|
|
||||||
*/
|
|
||||||
LedControl lc=LedControl(12,11,10,1);
|
|
||||||
|
|
||||||
/* we always wait a bit between updates of the display */
|
|
||||||
unsigned long delaytime=100;
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
/*
|
|
||||||
The MAX72XX is in power-saving mode on startup,
|
|
||||||
we have to do a wakeup call
|
|
||||||
*/
|
|
||||||
lc.shutdown(0,false);
|
|
||||||
/* Set the brightness to a medium values */
|
|
||||||
lc.setIntensity(0,8);
|
|
||||||
/* and clear the display */
|
|
||||||
lc.clearDisplay(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
This method will display the characters for the
|
|
||||||
word "Arduino" one after the other on the matrix.
|
|
||||||
(you need at least 5x7 leds to see the whole chars)
|
|
||||||
*/
|
|
||||||
void writeArduinoOnMatrix() {
|
|
||||||
/* here is the data for the characters */
|
|
||||||
byte a[5]={B01111110,B10001000,B10001000,B10001000,B01111110};
|
|
||||||
byte r[5]={B00111110,B00010000,B00100000,B00100000,B00010000};
|
|
||||||
byte d[5]={B00011100,B00100010,B00100010,B00010010,B11111110};
|
|
||||||
byte u[5]={B00111100,B00000010,B00000010,B00000100,B00111110};
|
|
||||||
byte i[5]={B00000000,B00100010,B10111110,B00000010,B00000000};
|
|
||||||
byte n[5]={B00111110,B00010000,B00100000,B00100000,B00011110};
|
|
||||||
byte o[5]={B00011100,B00100010,B00100010,B00100010,B00011100};
|
|
||||||
|
|
||||||
/* now display them one by one with a small delay */
|
|
||||||
lc.setRow(0,0,a[0]);
|
|
||||||
lc.setRow(0,1,a[1]);
|
|
||||||
lc.setRow(0,2,a[2]);
|
|
||||||
lc.setRow(0,3,a[3]);
|
|
||||||
lc.setRow(0,4,a[4]);
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setRow(0,0,r[0]);
|
|
||||||
lc.setRow(0,1,r[1]);
|
|
||||||
lc.setRow(0,2,r[2]);
|
|
||||||
lc.setRow(0,3,r[3]);
|
|
||||||
lc.setRow(0,4,r[4]);
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setRow(0,0,d[0]);
|
|
||||||
lc.setRow(0,1,d[1]);
|
|
||||||
lc.setRow(0,2,d[2]);
|
|
||||||
lc.setRow(0,3,d[3]);
|
|
||||||
lc.setRow(0,4,d[4]);
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setRow(0,0,u[0]);
|
|
||||||
lc.setRow(0,1,u[1]);
|
|
||||||
lc.setRow(0,2,u[2]);
|
|
||||||
lc.setRow(0,3,u[3]);
|
|
||||||
lc.setRow(0,4,u[4]);
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setRow(0,0,i[0]);
|
|
||||||
lc.setRow(0,1,i[1]);
|
|
||||||
lc.setRow(0,2,i[2]);
|
|
||||||
lc.setRow(0,3,i[3]);
|
|
||||||
lc.setRow(0,4,i[4]);
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setRow(0,0,n[0]);
|
|
||||||
lc.setRow(0,1,n[1]);
|
|
||||||
lc.setRow(0,2,n[2]);
|
|
||||||
lc.setRow(0,3,n[3]);
|
|
||||||
lc.setRow(0,4,n[4]);
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setRow(0,0,o[0]);
|
|
||||||
lc.setRow(0,1,o[1]);
|
|
||||||
lc.setRow(0,2,o[2]);
|
|
||||||
lc.setRow(0,3,o[3]);
|
|
||||||
lc.setRow(0,4,o[4]);
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setRow(0,0,0);
|
|
||||||
lc.setRow(0,1,0);
|
|
||||||
lc.setRow(0,2,0);
|
|
||||||
lc.setRow(0,3,0);
|
|
||||||
lc.setRow(0,4,0);
|
|
||||||
delay(delaytime);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
This function lights up a some Leds in a row.
|
|
||||||
The pattern will be repeated on every row.
|
|
||||||
The pattern will blink along with the row-number.
|
|
||||||
row number 4 (index==3) will blink 4 times etc.
|
|
||||||
*/
|
|
||||||
void rows() {
|
|
||||||
for(int row=0;row<8;row++) {
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setRow(0,row,B10100000);
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setRow(0,row,(byte)0);
|
|
||||||
for(int i=0;i<row;i++) {
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setRow(0,row,B10100000);
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setRow(0,row,(byte)0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
This function lights up a some Leds in a column.
|
|
||||||
The pattern will be repeated on every column.
|
|
||||||
The pattern will blink along with the column-number.
|
|
||||||
column number 4 (index==3) will blink 4 times etc.
|
|
||||||
*/
|
|
||||||
void columns() {
|
|
||||||
for(int col=0;col<8;col++) {
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setColumn(0,col,B10100000);
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setColumn(0,col,(byte)0);
|
|
||||||
for(int i=0;i<col;i++) {
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setColumn(0,col,B10100000);
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setColumn(0,col,(byte)0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
This function will light up every Led on the matrix.
|
|
||||||
The led will blink along with the row-number.
|
|
||||||
row number 4 (index==3) will blink 4 times etc.
|
|
||||||
*/
|
|
||||||
void single() {
|
|
||||||
for(int row=0;row<8;row++) {
|
|
||||||
for(int col=0;col<8;col++) {
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setLed(0,row,col,true);
|
|
||||||
delay(delaytime);
|
|
||||||
for(int i=0;i<col;i++) {
|
|
||||||
lc.setLed(0,row,col,false);
|
|
||||||
delay(delaytime);
|
|
||||||
lc.setLed(0,row,col,true);
|
|
||||||
delay(delaytime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
writeArduinoOnMatrix();
|
|
||||||
rows();
|
|
||||||
columns();
|
|
||||||
single();
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
#######################################
|
|
||||||
# Syntax Coloring Map For LedControl
|
|
||||||
#######################################
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Datatypes (KEYWORD1)
|
|
||||||
#######################################
|
|
||||||
|
|
||||||
LedControl KEYWORD1
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Methods and Functions (KEYWORD2)
|
|
||||||
#######################################
|
|
||||||
|
|
||||||
shutdown KEYWORD2
|
|
||||||
setScanLimit KEYWORD2
|
|
||||||
setIntensity KEYWORD2
|
|
||||||
clearDisplay KEYWORD2
|
|
||||||
setLed KEYWORD2
|
|
||||||
setRow KEYWORD2
|
|
||||||
setColumn KEYWORD2
|
|
||||||
setDigit KEYWORD2
|
|
||||||
setChar KEYWORD2
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Constants (LITERAL1)
|
|
||||||
#######################################
|
|
||||||
|
|
||||||
30
README.md
@@ -1,4 +1,4 @@
|
|||||||
DCF77 Analyzer / Clock
|
DCF77 Analyzer/Clock v2.0
|
||||||
|
|
||||||
|
|
||||||
This sketch is free software; you can redistribute it and/or
|
This sketch is free software; you can redistribute it and/or
|
||||||
@@ -16,17 +16,10 @@
|
|||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
|
||||||
The C++ code is far from optimized because I myself am an Arduino and C++ novice.
|
This C++ code is far from optimized because I myself am an Arduino and C++ novice.
|
||||||
But even after learning some more now, I want to keep the code simpel and readable.
|
But even after learning some more now, I want to keep the code simpel and readable.
|
||||||
That is why I maybe over-documented the code to help understand what's going on.
|
That is why I maybe over-documented the code to help understand what's going on.
|
||||||
|
|
||||||
HELP WANTED:
|
|
||||||
I'm not experienced enough to get to the point where the second-tick
|
|
||||||
of the Real Time Clock display is exactly in sync with the DCF pulse.
|
|
||||||
Now there's a small time lag.
|
|
||||||
If you have a solution, please let me know!
|
|
||||||
|
|
||||||
|
|
||||||
Erik de Ruiter
|
Erik de Ruiter
|
||||||
2014-2016
|
2014-2016
|
||||||
|
|
||||||
@@ -34,9 +27,20 @@
|
|||||||
|
|
||||||
May 2014 First version
|
May 2014 First version
|
||||||
March 2016 - big overhaul...
|
March 2016 - big overhaul...
|
||||||
|
July 2016 - Start with building the v2.0 Clock and adapting the sketch
|
||||||
|
|
||||||
|
Version 2.0 - August 2016
|
||||||
|
- This sketch is adapted for my 2.0 version of the DCF/Analyzer Clock. It used the Arduino MEGA and the DCF Superfilter
|
||||||
|
by default and to drive the many seperate LED's I now use the ports of an Arduino Mega instead of a Maxim 7219 chip.
|
||||||
|
This is because driving LED's with many different Voltage/Current specs is problematic with the Maxim chip.
|
||||||
|
Lighting additional LED's for expample will influence (dim) the LED's already on. As I'm not an electronics engineer
|
||||||
|
my only solution was to use the extra ports of the Arduino Mega. Ofcourse you can use transistors or extra chips to
|
||||||
|
drive the LED's but for me this was the obvious solution.
|
||||||
|
- Removed all the code to use Maxim 72xx chips with Common Anode displays
|
||||||
|
|
||||||
|
|
||||||
Version 1.72
|
|
||||||
|
Version 1.72 - May 2016
|
||||||
- Option: Use a cheap Ebay PIR detector to shut off selectable display's when no activity is detected.
|
- Option: Use a cheap Ebay PIR detector to shut off selectable display's when no activity is detected.
|
||||||
The switch off delay can be set by the user to prevent the display shutting of if a person
|
The switch off delay can be set by the user to prevent the display shutting of if a person
|
||||||
is not moving but the display should be on.
|
is not moving but the display should be on.
|
||||||
@@ -77,8 +81,8 @@
|
|||||||
can now be configured somewhat easier by editing two variables POWERSAVINGONTIME and POWERSAVINGOFFTIME.
|
can now be configured somewhat easier by editing two variables POWERSAVINGONTIME and POWERSAVINGOFFTIME.
|
||||||
- changed some variable names:
|
- changed some variable names:
|
||||||
- Maxim instances 'lc' and 'lc1' are now MaximCC and MaximCA
|
- Maxim instances 'lc' and 'lc1' are now MaximCC and MaximCA
|
||||||
- Display description MaximDcfTime is now MaximTemperature
|
- Display description MaximDcfTime is now DisplayTempWeek
|
||||||
- DCF77SOUNDPIN is now BUZZERPIN
|
- DCF77SOUNDPIN is now BUZZERSWITCHPIN
|
||||||
- LED/Display test after power up now build in
|
- LED/Display test after power up now build in
|
||||||
|
|
||||||
|
|
||||||
@@ -128,7 +132,7 @@
|
|||||||
The only thing is you can't see it... ;)
|
The only thing is you can't see it... ;)
|
||||||
|
|
||||||
DCF beep:
|
DCF beep:
|
||||||
With a switch, connected to pin BUZZERPIN, you can hear the received DCF bits coming in.
|
With a switch, connected to pin BUZZERSWITCHPIN, you can hear the received DCF bits coming in.
|
||||||
The tone duration is equivalent to pulse width of the DCF bits, so either 100 or 200 ms.
|
The tone duration is equivalent to pulse width of the DCF bits, so either 100 or 200 ms.
|
||||||
|
|
||||||
Miscelleanous:
|
Miscelleanous:
|
||||||
|
|||||||