First Commit
commit
31565dcde2
|
@ -0,0 +1 @@
|
||||||
|
.pio
|
|
@ -0,0 +1,2 @@
|
||||||
|
*~
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
MAX7219
|
||||||
|
=======
|
||||||
|
|
||||||
|
Arduino library for MAX7219 display using SPI.
|
||||||
|
|
||||||
|
|
||||||
|
For details about the theory, wiring, schematic, etc. see:
|
||||||
|
|
||||||
|
http://www.gammon.com.au/forum/?id=11516
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
// Demo of MAX7219 library
|
||||||
|
// Author: Nick Gammon
|
||||||
|
// Date: 17 March 2015
|
||||||
|
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <bitBangedSPI.h>
|
||||||
|
#include <MAX7219.h>
|
||||||
|
|
||||||
|
const byte chips = 1;
|
||||||
|
|
||||||
|
// 1 chip, bit banged SPI on pins 6, 7, 8
|
||||||
|
MAX7219 display (chips, 6, 7, 8); // Chips / LOAD / DIN / CLK
|
||||||
|
|
||||||
|
void setup ()
|
||||||
|
{
|
||||||
|
display.begin ();
|
||||||
|
display.sendString ("HELLO _-_-_-_-");
|
||||||
|
delay (2000);
|
||||||
|
display.setIntensity (2);
|
||||||
|
display.sendString ("Lo Light");
|
||||||
|
delay (2000);
|
||||||
|
display.setIntensity (6);
|
||||||
|
} // end of setup
|
||||||
|
|
||||||
|
// scrolling display of all available characters
|
||||||
|
void loop ()
|
||||||
|
{
|
||||||
|
char buf [(chips * 8) + 1];
|
||||||
|
for (char i = '0'; i < 'z'; i++)
|
||||||
|
{
|
||||||
|
for (byte j = 0; j < (chips * 8); j++)
|
||||||
|
buf [j] = i + j;
|
||||||
|
buf [chips * 8] = 0;
|
||||||
|
display.sendString (buf);
|
||||||
|
delay (1000);
|
||||||
|
} // end of for loop
|
||||||
|
} // end of loop
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <bitBangedSPI.h>
|
||||||
|
#include <MAX7219.h>
|
||||||
|
|
||||||
|
const byte chips = 1;
|
||||||
|
|
||||||
|
// 1 chip, bit banged SPI on pins 6, 7, 8
|
||||||
|
MAX7219 display (chips, 6, 7, 8); // Chips / LOAD / DIN / CLK
|
||||||
|
|
||||||
|
const char message [] = "Hello there - testing 123456789 ";
|
||||||
|
|
||||||
|
void setup ()
|
||||||
|
{
|
||||||
|
display.begin ();
|
||||||
|
} // end of setup
|
||||||
|
|
||||||
|
unsigned long lastMoved = 0;
|
||||||
|
unsigned long MOVE_INTERVAL = 500; // mS
|
||||||
|
unsigned int messageOffset;
|
||||||
|
|
||||||
|
void updateDisplay ()
|
||||||
|
{
|
||||||
|
const unsigned int messageLength = strlen (message);
|
||||||
|
|
||||||
|
// get each byte required
|
||||||
|
for (byte i = 0; i < (8 * chips); i++)
|
||||||
|
{
|
||||||
|
// find the offset in the message array
|
||||||
|
unsigned int charOffset = messageOffset + i;
|
||||||
|
// if we have passed the end, go back to the start
|
||||||
|
if (charOffset >= messageLength)
|
||||||
|
charOffset -= messageLength;
|
||||||
|
// send that character
|
||||||
|
display.sendChar (i, message [charOffset]);
|
||||||
|
}
|
||||||
|
// next time show one character on
|
||||||
|
if (messageOffset++ >= messageLength)
|
||||||
|
messageOffset = 0;
|
||||||
|
} // end of updateDisplay
|
||||||
|
|
||||||
|
void loop ()
|
||||||
|
{
|
||||||
|
|
||||||
|
// update display if time is up
|
||||||
|
if (millis () - lastMoved >= MOVE_INTERVAL)
|
||||||
|
{
|
||||||
|
updateDisplay ();
|
||||||
|
lastMoved = millis ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// do other stuff here
|
||||||
|
|
||||||
|
} // end of loop
|
||||||
|
|
|
@ -0,0 +1,226 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
MAX7219 class
|
||||||
|
Author: Nick Gammon
|
||||||
|
Date: 17 March 2015
|
||||||
|
|
||||||
|
|
||||||
|
PERMISSION TO DISTRIBUTE
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
LIMITATION OF LIABILITY
|
||||||
|
|
||||||
|
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 <SPI.h>
|
||||||
|
#include <bitBangedSPI.h>
|
||||||
|
#include <MAX7219.h>
|
||||||
|
#include <MAX7219_font.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Wiring:
|
||||||
|
|
||||||
|
Hardware SPI:
|
||||||
|
|
||||||
|
Wire DIN (data) to the MOSI pin (D11 on a Uno)
|
||||||
|
Wire CLK (clock) to the SCK pin (D13 on a Uno)
|
||||||
|
Wire LOAD to the /SS (slave select) pin (D10 on a Uno)
|
||||||
|
|
||||||
|
Make an instance of the class:
|
||||||
|
|
||||||
|
MAX7219 myDisplay (1, 10); // 1 chip, and then specify the LOAD pin only
|
||||||
|
|
||||||
|
Bit-banged SPI:
|
||||||
|
|
||||||
|
Wire LOAD, DIN, CLK to any pins of your choice.
|
||||||
|
|
||||||
|
Make an instance of the class:
|
||||||
|
|
||||||
|
MAX7219 myDisplay (2, 6, 7, 8); // 2 chips, then specify the LOAD, DIN, CLK pins
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
Initialize:
|
||||||
|
|
||||||
|
myDisplay.begin ();
|
||||||
|
|
||||||
|
Shut down:
|
||||||
|
|
||||||
|
myDisplay.end ();
|
||||||
|
|
||||||
|
Write to display:
|
||||||
|
|
||||||
|
myDisplay.sendString ("HELLO");
|
||||||
|
|
||||||
|
Set the intensity (from 0 to 15):
|
||||||
|
|
||||||
|
myDisplay.setIntensity (8);
|
||||||
|
|
||||||
|
For the class to compile you need to include these three files:
|
||||||
|
|
||||||
|
SPI.h
|
||||||
|
bitBangedSPI.h
|
||||||
|
MAX7219.h
|
||||||
|
|
||||||
|
You can obtain the bitBangedSPI library from:
|
||||||
|
|
||||||
|
https://github.com/nickgammon/bitBangedSPI
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
MAX7219::~MAX7219 ()
|
||||||
|
{
|
||||||
|
end ();
|
||||||
|
} // end of destructor
|
||||||
|
|
||||||
|
void MAX7219::begin ()
|
||||||
|
{
|
||||||
|
pinMode (load_, OUTPUT);
|
||||||
|
digitalWrite (load_, HIGH);
|
||||||
|
|
||||||
|
// prepare SPI
|
||||||
|
if (bitBanged_)
|
||||||
|
{
|
||||||
|
if (bbSPI_ == NULL)
|
||||||
|
bbSPI_ = new bitBangedSPI (din_, bitBangedSPI::NO_PIN, clock_);
|
||||||
|
bbSPI_->begin ();
|
||||||
|
} // end of bit banged SPI
|
||||||
|
else
|
||||||
|
{ // hardware SPI
|
||||||
|
SPI.begin ();
|
||||||
|
} // end of hardware SPI
|
||||||
|
|
||||||
|
sendToAll (MAX7219_REG_SCANLIMIT, 7); // show 8 digits
|
||||||
|
sendToAll (MAX7219_REG_DECODEMODE, 0); // use bit patterns
|
||||||
|
sendToAll (MAX7219_REG_DISPLAYTEST, 0); // no display test
|
||||||
|
sendToAll (MAX7219_REG_INTENSITY, 15); // character intensity: range: 0 to 15
|
||||||
|
sendString (""); // clear display
|
||||||
|
sendToAll (MAX7219_REG_SHUTDOWN, 1); // not in shutdown mode (ie. start it up)
|
||||||
|
} // end of MAX7219::begin
|
||||||
|
|
||||||
|
void MAX7219::end ()
|
||||||
|
{
|
||||||
|
sendToAll (MAX7219_REG_SHUTDOWN, 0); // shutdown mode (ie. turn it off)
|
||||||
|
|
||||||
|
if (bbSPI_ != NULL)
|
||||||
|
{
|
||||||
|
delete bbSPI_;
|
||||||
|
bbSPI_ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bitBanged_)
|
||||||
|
SPI.end ();
|
||||||
|
|
||||||
|
} // end of MAX7219::end
|
||||||
|
|
||||||
|
void MAX7219::wakeUp ()
|
||||||
|
{
|
||||||
|
sendToAll (MAX7219_REG_SHUTDOWN, 1); // shutdown mode (ie. turn it off)
|
||||||
|
}
|
||||||
|
void MAX7219::sleep ()
|
||||||
|
{
|
||||||
|
sendToAll (MAX7219_REG_SHUTDOWN, 0); // shutdown mode (ie. turn it off)
|
||||||
|
}
|
||||||
|
void MAX7219::setIntensity (const byte amount)
|
||||||
|
{
|
||||||
|
sendToAll (MAX7219_REG_INTENSITY, amount & 0xF); // character intensity: range: 0 to 15
|
||||||
|
} // end of MAX7219::setIntensity
|
||||||
|
|
||||||
|
// send one byte to MAX7219
|
||||||
|
void MAX7219::sendByte (const byte reg, const byte data)
|
||||||
|
{
|
||||||
|
if (bitBanged_)
|
||||||
|
{
|
||||||
|
if (bbSPI_ != NULL)
|
||||||
|
{
|
||||||
|
bbSPI_->transfer (reg);
|
||||||
|
bbSPI_->transfer (data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SPI.transfer (reg);
|
||||||
|
SPI.transfer (data);
|
||||||
|
}
|
||||||
|
} // end of sendByte
|
||||||
|
|
||||||
|
void MAX7219::sendToAll (const byte reg, const byte data)
|
||||||
|
{
|
||||||
|
digitalWrite (load_, LOW);
|
||||||
|
for (byte chip = 0; chip < chips_; chip++)
|
||||||
|
sendByte (reg, data);
|
||||||
|
digitalWrite (load_, HIGH);
|
||||||
|
} // end of sendToAll
|
||||||
|
|
||||||
|
// send one character (data) to position (pos) with or without decimal place
|
||||||
|
// pos is 0 to 7
|
||||||
|
void MAX7219::sendChar (const byte pos, const char data, const bool dp)
|
||||||
|
{
|
||||||
|
byte converted = 0b0000001; // hyphen as default
|
||||||
|
|
||||||
|
// look up bit pattern if possible
|
||||||
|
if (data >= ' ' && data <= 'z')
|
||||||
|
converted = pgm_read_byte (&MAX7219_font [data - ' ']);
|
||||||
|
// 'or' in the decimal point if required
|
||||||
|
if (dp)
|
||||||
|
converted |= 0b10000000;
|
||||||
|
|
||||||
|
// start sending
|
||||||
|
digitalWrite (load_, LOW);
|
||||||
|
|
||||||
|
// segment is in range 1 to 8
|
||||||
|
const byte segment = 8 - (pos % 8);
|
||||||
|
// for each daisy-chained display we need an extra NOP
|
||||||
|
const byte nopCount = pos / 8;
|
||||||
|
// send extra NOPs to push the data out to extra displays
|
||||||
|
for (byte i = 0; i < nopCount; i++)
|
||||||
|
sendByte (MAX7219_REG_NOOP, MAX7219_REG_NOOP);
|
||||||
|
// send the segment number and data
|
||||||
|
sendByte (segment, converted);
|
||||||
|
// end with enough NOPs so later chips don't update
|
||||||
|
for (int i = 0; i < chips_ - nopCount - 1; i++)
|
||||||
|
sendByte (MAX7219_REG_NOOP, MAX7219_REG_NOOP);
|
||||||
|
|
||||||
|
// all done!
|
||||||
|
digitalWrite (load_, HIGH);
|
||||||
|
} // end of sendChar
|
||||||
|
|
||||||
|
// write an entire null-terminated string to the LEDs
|
||||||
|
void MAX7219::sendString (const char * s)
|
||||||
|
{
|
||||||
|
byte pos;
|
||||||
|
|
||||||
|
for (pos = 0; pos < (chips_ * 8) && *s; pos++)
|
||||||
|
{
|
||||||
|
boolean dp = s [1] == '.';
|
||||||
|
sendChar (pos, *s++, dp); // turn decimal place on if next char is a dot
|
||||||
|
if (dp) // skip dot
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// space out rest
|
||||||
|
while (pos < (chips_ * 8))
|
||||||
|
sendChar (pos++, ' ');
|
||||||
|
|
||||||
|
|
||||||
|
} // end of sendString
|
|
@ -0,0 +1,50 @@
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
class MAX7219
|
||||||
|
{
|
||||||
|
// pins
|
||||||
|
const byte chips_;
|
||||||
|
const byte load_;
|
||||||
|
const byte din_;
|
||||||
|
const byte clock_;
|
||||||
|
const bool bitBanged_;
|
||||||
|
bitBangedSPI * bbSPI_;
|
||||||
|
|
||||||
|
void sendByte (const byte reg, const byte data);
|
||||||
|
void sendToAll (const byte reg, const byte data);
|
||||||
|
|
||||||
|
// registers
|
||||||
|
enum {
|
||||||
|
MAX7219_REG_NOOP = 0x0,
|
||||||
|
// codes 1 to 8 are digit positions 1 to 8
|
||||||
|
MAX7219_REG_DECODEMODE = 0x9,
|
||||||
|
MAX7219_REG_INTENSITY = 0xA,
|
||||||
|
MAX7219_REG_SCANLIMIT = 0xB,
|
||||||
|
MAX7219_REG_SHUTDOWN = 0xC,
|
||||||
|
MAX7219_REG_DISPLAYTEST = 0xF,
|
||||||
|
}; // end of enum
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
MAX7219 (const byte chips,
|
||||||
|
const byte load,
|
||||||
|
const byte din = 0,
|
||||||
|
const byte clock = 0)
|
||||||
|
: chips_ (chips), load_ (load), din_ (din), clock_ (clock),
|
||||||
|
bitBanged_ ((din | clock) != 0), bbSPI_ (NULL) { }
|
||||||
|
|
||||||
|
~MAX7219 (); // destructor
|
||||||
|
void begin ();
|
||||||
|
void end ();
|
||||||
|
|
||||||
|
void wakeUp ();
|
||||||
|
void sleep ();
|
||||||
|
|
||||||
|
void sendChar (const byte pos, const char data, const bool dp = false);
|
||||||
|
void sendString (const char * s);
|
||||||
|
void setIntensity (const byte amount); // 0 to 15
|
||||||
|
|
||||||
|
static const byte HYPHEN = 0b0000001;
|
||||||
|
|
||||||
|
}; // end of class MAX7219
|
|
@ -0,0 +1,97 @@
|
||||||
|
// MAX7219_font.h
|
||||||
|
|
||||||
|
// bit patterns for the letters / digits
|
||||||
|
|
||||||
|
const byte MAX7219_font [91] PROGMEM = {
|
||||||
|
0b0000000, // ' '
|
||||||
|
MAX7219::HYPHEN, // '!'
|
||||||
|
MAX7219::HYPHEN, // '"'
|
||||||
|
MAX7219::HYPHEN, // '#'
|
||||||
|
MAX7219::HYPHEN, // '$'
|
||||||
|
MAX7219::HYPHEN, // '%'
|
||||||
|
MAX7219::HYPHEN, // '&'
|
||||||
|
MAX7219::HYPHEN, // '''
|
||||||
|
0b1001110, // '(' - same as [
|
||||||
|
0b1111000, // ')' - same as ]
|
||||||
|
MAX7219::HYPHEN, // '*'
|
||||||
|
MAX7219::HYPHEN, // '+'
|
||||||
|
MAX7219::HYPHEN, // ','
|
||||||
|
MAX7219::HYPHEN, // '-' - LOL *is* a hyphen
|
||||||
|
0b0000000, // '.' (done by turning DP on)
|
||||||
|
MAX7219::HYPHEN, // '/'
|
||||||
|
0b1111110, // '0'
|
||||||
|
0b0110000, // '1'
|
||||||
|
0b1101101, // '2'
|
||||||
|
0b1111001, // '3'
|
||||||
|
0b0110011, // '4'
|
||||||
|
0b1011011, // '5'
|
||||||
|
0b1011111, // '6'
|
||||||
|
0b1110000, // '7'
|
||||||
|
0b1111111, // '8'
|
||||||
|
0b1111011, // '9'
|
||||||
|
MAX7219::HYPHEN, // ':'
|
||||||
|
MAX7219::HYPHEN, // ';'
|
||||||
|
MAX7219::HYPHEN, // '<'
|
||||||
|
MAX7219::HYPHEN, // '='
|
||||||
|
MAX7219::HYPHEN, // '>'
|
||||||
|
MAX7219::HYPHEN, // '?'
|
||||||
|
MAX7219::HYPHEN, // '@'
|
||||||
|
0b1110111, // 'A'
|
||||||
|
0b0011111, // 'B'
|
||||||
|
0b1001110, // 'C'
|
||||||
|
0b0111101, // 'D'
|
||||||
|
0b1001111, // 'E'
|
||||||
|
0b1000111, // 'F'
|
||||||
|
0b1011110, // 'G'
|
||||||
|
0b0110111, // 'H'
|
||||||
|
0b0110000, // 'I' - same as 1
|
||||||
|
0b0111100, // 'J'
|
||||||
|
MAX7219::HYPHEN, // 'K'
|
||||||
|
0b0001110, // 'L'
|
||||||
|
MAX7219::HYPHEN, // 'M'
|
||||||
|
0b0010101, // 'N'
|
||||||
|
0b1111110, // 'O' - same as 0
|
||||||
|
0b1100111, // 'P'
|
||||||
|
MAX7219::HYPHEN, // 'Q'
|
||||||
|
0b0000101, // 'R'
|
||||||
|
0b1011011, // 'S'
|
||||||
|
0b0000111, // 'T'
|
||||||
|
0b0111110, // 'U'
|
||||||
|
MAX7219::HYPHEN, // 'V'
|
||||||
|
MAX7219::HYPHEN, // 'W'
|
||||||
|
MAX7219::HYPHEN, // 'X'
|
||||||
|
0b0100111, // 'Y'
|
||||||
|
MAX7219::HYPHEN, // 'Z'
|
||||||
|
0b1001110, // '[' - same as C
|
||||||
|
MAX7219::HYPHEN, // backslash
|
||||||
|
0b1111000, // ']'
|
||||||
|
MAX7219::HYPHEN, // '^'
|
||||||
|
0b0001000, // '_'
|
||||||
|
MAX7219::HYPHEN, // '`'
|
||||||
|
0b1110111, // 'a'
|
||||||
|
0b0011111, // 'b'
|
||||||
|
0b0001101, // 'c'
|
||||||
|
0b0111101, // 'd'
|
||||||
|
0b1001111, // 'e'
|
||||||
|
0b1000111, // 'f'
|
||||||
|
0b1011110, // 'g'
|
||||||
|
0b0010111, // 'h'
|
||||||
|
0b0010000, // 'i'
|
||||||
|
0b0111100, // 'j'
|
||||||
|
MAX7219::HYPHEN, // 'k'
|
||||||
|
0b0001110, // 'l'
|
||||||
|
MAX7219::HYPHEN, // 'm'
|
||||||
|
0b0010101, // 'n'
|
||||||
|
0b1111110, // 'o' - same as 0
|
||||||
|
0b1100111, // 'p'
|
||||||
|
MAX7219::HYPHEN, // 'q'
|
||||||
|
0b0000101, // 'r'
|
||||||
|
0b1011011, // 's'
|
||||||
|
0b0000111, // 't'
|
||||||
|
0b0011100, // 'u'
|
||||||
|
MAX7219::HYPHEN, // 'v'
|
||||||
|
MAX7219::HYPHEN, // 'w'
|
||||||
|
MAX7219::HYPHEN, // 'x'
|
||||||
|
0b0100111, // 'y'
|
||||||
|
MAX7219::HYPHEN, // 'z'
|
||||||
|
}; // end of MAX7219_font
|
|
@ -0,0 +1,12 @@
|
||||||
|
bitBangedSPI
|
||||||
|
============
|
||||||
|
|
||||||
|
SPI class for Arduino Uno and similar.
|
||||||
|
|
||||||
|
For details and documentation see:
|
||||||
|
|
||||||
|
http://www.gammon.com.au/forum/?id=10892
|
||||||
|
|
||||||
|
In particular:
|
||||||
|
|
||||||
|
http://www.gammon.com.au/forum/?id=10892&reply=6#reply6
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Bit-banged SPI class
|
||||||
|
Author: Nick Gammon
|
||||||
|
Date: 24 March 2013
|
||||||
|
|
||||||
|
|
||||||
|
PERMISSION TO DISTRIBUTE
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
LIMITATION OF LIABILITY
|
||||||
|
|
||||||
|
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 <bitBangedSPI.h>
|
||||||
|
|
||||||
|
void bitBangedSPI::begin ()
|
||||||
|
{
|
||||||
|
if (mosi_ != NO_PIN)
|
||||||
|
pinMode (mosi_, OUTPUT);
|
||||||
|
if (miso_ != NO_PIN)
|
||||||
|
pinMode (miso_, INPUT);
|
||||||
|
pinMode (sck_, OUTPUT);
|
||||||
|
} // end of bitBangedSPI::begin
|
||||||
|
|
||||||
|
|
||||||
|
// Bit Banged SPI transfer
|
||||||
|
byte bitBangedSPI::transfer (byte c)
|
||||||
|
{
|
||||||
|
// loop for each bit
|
||||||
|
for (byte bit = 0; bit < 8; bit++)
|
||||||
|
{
|
||||||
|
// set up MOSI on falling edge of previous SCK (sampled on rising edge)
|
||||||
|
if (mosi_ != NO_PIN)
|
||||||
|
{
|
||||||
|
if (c & 0x80)
|
||||||
|
digitalWrite (mosi_, HIGH);
|
||||||
|
else
|
||||||
|
digitalWrite (mosi_, LOW);
|
||||||
|
}
|
||||||
|
// finished with MS bit, get read to receive next bit
|
||||||
|
c <<= 1;
|
||||||
|
|
||||||
|
// read MISO
|
||||||
|
if (miso_ != NO_PIN)
|
||||||
|
c |= digitalRead (miso_) != 0;
|
||||||
|
|
||||||
|
// clock high
|
||||||
|
digitalWrite (sck_, HIGH);
|
||||||
|
|
||||||
|
// delay between rise and fall of clock
|
||||||
|
delayMicroseconds (delayUs_);
|
||||||
|
|
||||||
|
// clock low
|
||||||
|
digitalWrite (sck_, LOW);
|
||||||
|
|
||||||
|
// delay between rise and fall of clock
|
||||||
|
delayMicroseconds (delayUs_);
|
||||||
|
} // end of for loop, for each bit
|
||||||
|
|
||||||
|
return c;
|
||||||
|
} // end of bitBangedSPI::transfer
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Bit-banged SPI class
|
||||||
|
Author: Nick Gammon
|
||||||
|
Date: 24 March 2013
|
||||||
|
|
||||||
|
|
||||||
|
PERMISSION TO DISTRIBUTE
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
LIMITATION OF LIABILITY
|
||||||
|
|
||||||
|
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 <Arduino.h>
|
||||||
|
|
||||||
|
class bitBangedSPI
|
||||||
|
{
|
||||||
|
// pins
|
||||||
|
const int mosi_;
|
||||||
|
const int miso_;
|
||||||
|
const int sck_;
|
||||||
|
// delay for clock being high
|
||||||
|
unsigned long delayUs_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
bitBangedSPI (const int mosi, const int miso, const int sck, const unsigned long delayUs = 4)
|
||||||
|
: mosi_ (mosi), miso_ (miso), sck_ (sck), delayUs_ (delayUs) { }
|
||||||
|
|
||||||
|
void begin ();
|
||||||
|
byte transfer (byte input);
|
||||||
|
|
||||||
|
enum { NO_PIN = -1 };
|
||||||
|
|
||||||
|
}; // end of bitBangedSPI
|
|
@ -0,0 +1,17 @@
|
||||||
|
; PlatformIO Project Configuration File
|
||||||
|
;
|
||||||
|
; Build options: build flags, source filter
|
||||||
|
; Upload options: custom upload port, speed and extra flags
|
||||||
|
; Library options: dependencies, extra library storages
|
||||||
|
; Advanced options: extra scripting
|
||||||
|
;
|
||||||
|
; Please visit documentation for the other options and examples
|
||||||
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
|
[platformio]
|
||||||
|
default_envs = nanoatmega328
|
||||||
|
|
||||||
|
[env:nanoatmega328]
|
||||||
|
platform = atmelavr
|
||||||
|
framework = arduino
|
||||||
|
board = nanoatmega328
|
|
@ -0,0 +1,332 @@
|
||||||
|
// /bin/avrdude -C//etc/avrdude.conf -v -patmega328p -carduino -P/dev/ttyUSB0 -b57600 -D -Uflash:w:/tmp/arduino_build_80915/arduino-sensors-serial.ino.hex:i
|
||||||
|
// /bin/avrdude -C//etc/avrdude.conf -v -patmega328p -carduino -P/dev/ttyUSB0 -b115200 -D -Uflash:w:/tmp/arduino_build_80915/arduino-sensors-serial.ino.hex:i
|
||||||
|
|
||||||
|
#include <SimpleDHT.h>
|
||||||
|
#include <RCSwitch.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <Wire.h>
|
||||||
|
#include <BH1750.h>
|
||||||
|
|
||||||
|
#include <bitBangedSPI.h>
|
||||||
|
#include <MAX7219.h>
|
||||||
|
|
||||||
|
#include <NonBlockingRtttl.h>
|
||||||
|
|
||||||
|
BH1750 lightMeter; // I2C SDA: A4, SCL: A5
|
||||||
|
|
||||||
|
RCSwitch mySwitch = RCSwitch();
|
||||||
|
|
||||||
|
const byte chips = 1;
|
||||||
|
// 1 chip, CS: 4
|
||||||
|
MAX7219 display (chips, 4);
|
||||||
|
|
||||||
|
const byte PIN_PIR = 2;
|
||||||
|
const byte PIN_BUZZER = 10;
|
||||||
|
const byte PIN_433 = 7;
|
||||||
|
const byte PIN_DHT22 = 8;
|
||||||
|
/*const byte PIN_LED_R = 5;
|
||||||
|
const byte PIN_LED_G = 6;
|
||||||
|
const byte PIN_LED_B = 9;*/
|
||||||
|
//PWM: 3, 5, 6, 9, 10, and 11
|
||||||
|
//SPI: 10 (SS), 11 (MOSI), 12 (MISO), 13 (SCK).
|
||||||
|
|
||||||
|
|
||||||
|
const unsigned long chacon_OFF = 1381716;
|
||||||
|
const unsigned long chacon_ON = 1381717;
|
||||||
|
const unsigned long chacondim_OFF = 1394004;
|
||||||
|
const unsigned long chacondim_ON = 1394005;
|
||||||
|
|
||||||
|
char mode = 'z';
|
||||||
|
String val;
|
||||||
|
|
||||||
|
SimpleDHT22 dht22;
|
||||||
|
|
||||||
|
unsigned long timemillis=millis();
|
||||||
|
const unsigned long timertemp = 30000;
|
||||||
|
unsigned long timemillislux=millis();
|
||||||
|
const unsigned long timerlux = 1000;
|
||||||
|
float oldtemperature = 0;
|
||||||
|
int oldhumidity = 0;
|
||||||
|
int oldpirstate = 0;
|
||||||
|
|
||||||
|
uint16_t oldlux = 0;
|
||||||
|
|
||||||
|
/*unsigned long cmmillis = 0;
|
||||||
|
short cmindex = -1;
|
||||||
|
const unsigned int cmmusic[] = { 230, 560, 450, 140, 670, 300, 520, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
*/
|
||||||
|
|
||||||
|
//const char * tetris = "tetris:d=4,o=5,b=160:e6,8b,8c6,8d6,16e6,16d6,8c6,8b,a,8a,8c6,e6,8d6,8c6,b,8b,8c6,d6,e6,c6,a,2a,8p,d6,8f6,a6,8g6,8f6,e6,8e6,8c6,e6,8d6,8c6,b,8b,8c6,d6,e6,c6,a,a";
|
||||||
|
//const char * arkanoid = "Arkanoid:d=4,o=5,b=140:8g6,16p,16g.6,2a#6,32p,8a6,8g6,8f6,8a6,2g6";
|
||||||
|
//const char * mario = "mario:d=4,o=5,b=100:16e6,16e6,32p,8e6,16c6,8e6,8g6,8p,8g,8p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,16p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16c7,16p,16c7,16c7,p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16d#6,8p,16d6,8p,16c6";
|
||||||
|
|
||||||
|
//t:d=4,o=5,b=100:c,p,c,p,c,p,c
|
||||||
|
|
||||||
|
String ptext;
|
||||||
|
boolean ptextstate = false;
|
||||||
|
short ptextindex = -1;
|
||||||
|
short ptextdirection = 1;
|
||||||
|
unsigned long ptextmillis = 0;
|
||||||
|
|
||||||
|
/** Affiche une couleur */
|
||||||
|
/*void displayColor(byte r, byte g, byte b) {
|
||||||
|
analogWrite(PIN_LED_R, ~r);
|
||||||
|
analogWrite(PIN_LED_G, ~g);
|
||||||
|
analogWrite(PIN_LED_B, ~b);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
void pirchange() {
|
||||||
|
int pirstate = digitalRead(2);
|
||||||
|
if(pirstate!=oldpirstate)
|
||||||
|
{
|
||||||
|
oldpirstate=pirstate;
|
||||||
|
if(pirstate == HIGH) {
|
||||||
|
Serial.println("p 1");
|
||||||
|
} else {
|
||||||
|
Serial.println("p 0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(9600);
|
||||||
|
// Emetteur connecté au pin #10 de l'Arduino
|
||||||
|
mySwitch.enableTransmit(PIN_433);
|
||||||
|
mySwitch.setRepeatTransmit(8);
|
||||||
|
//Serial.println("init ");
|
||||||
|
|
||||||
|
/*pinMode(PIN_LED_R, OUTPUT);
|
||||||
|
pinMode(PIN_LED_G, OUTPUT);
|
||||||
|
pinMode(PIN_LED_B, OUTPUT);
|
||||||
|
displayColor(0, 0, 0);*/
|
||||||
|
|
||||||
|
// Initialize the I2C bus (BH1750 library doesn't do this automatically)
|
||||||
|
Wire.begin();
|
||||||
|
// On esp8266 you can select SCL and SDA pins using Wire.begin(D4, D3);
|
||||||
|
|
||||||
|
lightMeter.begin();
|
||||||
|
|
||||||
|
pinMode(PIN_PIR, INPUT_PULLUP);
|
||||||
|
attachInterrupt(digitalPinToInterrupt(PIN_PIR), pirchange, CHANGE);
|
||||||
|
|
||||||
|
pinMode(PIN_BUZZER, OUTPUT);
|
||||||
|
|
||||||
|
display.begin ();
|
||||||
|
display.setIntensity (10);
|
||||||
|
display.sendString ("HELLO NG");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
/* Serial.print("allume ");
|
||||||
|
mySwitch.send(chacon_ON, 24);
|
||||||
|
delay(3000);
|
||||||
|
Serial.println("eteint ");
|
||||||
|
mySwitch.send(chacon_OFF, 24);
|
||||||
|
delay(3000); */
|
||||||
|
//Serial.print("allume ");
|
||||||
|
//mySwitch.send(chacondim_ON, 24);
|
||||||
|
//delay(3000);
|
||||||
|
//Serial.println("eteint ");
|
||||||
|
//mySwitch.send(chacondim_OFF, 24);
|
||||||
|
//delay(3000);
|
||||||
|
char schar;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(Serial.available() > 0)
|
||||||
|
{
|
||||||
|
schar=Serial.read();
|
||||||
|
if(schar != '\r' && schar != '\n')
|
||||||
|
{
|
||||||
|
if(mode == 'z') {
|
||||||
|
mode=schar;
|
||||||
|
} else {
|
||||||
|
//val=schar;
|
||||||
|
val.concat(schar);
|
||||||
|
//Serial.print(mode);
|
||||||
|
//Serial.println(val);
|
||||||
|
//mode='z'; }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Serial.print(mode);
|
||||||
|
// Serial.println(val.toInt());
|
||||||
|
long valint;
|
||||||
|
if(mode=='d')
|
||||||
|
{
|
||||||
|
valint=val.toInt();
|
||||||
|
if(valint==0) {
|
||||||
|
//Serial.println("Dimmer OFF");
|
||||||
|
mySwitch.send(chacondim_OFF, 24);
|
||||||
|
} else if(valint==1) {
|
||||||
|
//Serial.println("Dimmer ON");
|
||||||
|
mySwitch.send(chacondim_ON, 24);
|
||||||
|
}
|
||||||
|
} else if(mode=='s') {
|
||||||
|
valint=val.toInt();
|
||||||
|
if(valint==0) {
|
||||||
|
//Serial.println("Switch OFF");
|
||||||
|
mySwitch.send(chacon_OFF, 24);
|
||||||
|
} else if(valint==1) {
|
||||||
|
//Serial.println("Switch ON");
|
||||||
|
mySwitch.send(chacon_ON, 24);
|
||||||
|
}
|
||||||
|
/* } else if(mode=='l') {
|
||||||
|
byte r,g,b;
|
||||||
|
valint = strtol(val.c_str(), NULL, 16);
|
||||||
|
r = ((valint >> 16) & 0xFF);
|
||||||
|
g = ((valint >> 8) & 0xFF);
|
||||||
|
b = ((valint) & 0xFF);
|
||||||
|
displayColor(r,g,b); */
|
||||||
|
} else if(mode=='t' and ptextstate==false) {
|
||||||
|
display.sendString(val.c_str());
|
||||||
|
} else if(mode=='i') {
|
||||||
|
display.setIntensity(val.toInt());
|
||||||
|
} else if(mode=='m') {
|
||||||
|
valint=val.toInt();
|
||||||
|
if(valint==0) {
|
||||||
|
display.sleep();
|
||||||
|
} else if(valint==1) {
|
||||||
|
display.wakeUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if(mode=='b') {
|
||||||
|
valint=val.toInt();
|
||||||
|
if(valint==1) {
|
||||||
|
tone(PIN_BUZZER, 450, 250);
|
||||||
|
//toneAC(450, 10, 250);
|
||||||
|
delay(300);
|
||||||
|
tone(PIN_BUZZER, 450, 250);
|
||||||
|
//toneAC(450, 10, 250);
|
||||||
|
} else if(valint==2) {
|
||||||
|
tone(PIN_BUZZER, 450, 250);
|
||||||
|
//toneAC(450, 10, 250);
|
||||||
|
delay(300);
|
||||||
|
tone(PIN_BUZZER, 550, 250);
|
||||||
|
//toneAC(550, 10, 250);
|
||||||
|
} else if(valint==3) {
|
||||||
|
tone(PIN_BUZZER, 450, 250);
|
||||||
|
//toneAC(450, 10, 250);
|
||||||
|
delay(300);
|
||||||
|
tone(PIN_BUZZER, 350, 250);
|
||||||
|
//toneAC(350, 10, 250);
|
||||||
|
/* } else if(valint==4) {
|
||||||
|
cmindex = 0;
|
||||||
|
} else if(valint==5) {
|
||||||
|
noTone(PIN_BUZZER);
|
||||||
|
cmindex = -1;*/
|
||||||
|
}
|
||||||
|
} else if(mode=='c') {
|
||||||
|
rtttl::begin(PIN_BUZZER, val.c_str());
|
||||||
|
|
||||||
|
} else if(mode=='f') {
|
||||||
|
valint=val.toInt();
|
||||||
|
tone(PIN_BUZZER, valint, 250);
|
||||||
|
//toneAC(valint, 10, 250);
|
||||||
|
} else if(mode=='v') {
|
||||||
|
valint=val.toInt();
|
||||||
|
//char vsend[3];
|
||||||
|
unsigned long vsendl = 10759680;
|
||||||
|
//vsend[0]=0xa4;
|
||||||
|
//vsend[1]=0x2e;
|
||||||
|
//vsend[2] = 0x00;
|
||||||
|
vsendl += valint;
|
||||||
|
mySwitch.send(vsendl, 24);
|
||||||
|
} else if(mode=='p')
|
||||||
|
{
|
||||||
|
if(val=="")
|
||||||
|
{
|
||||||
|
ptextstate=false;
|
||||||
|
} else {
|
||||||
|
ptextstate=true;
|
||||||
|
if(val.length()<=8)
|
||||||
|
{
|
||||||
|
ptextindex=-1;
|
||||||
|
display.sendString(val.c_str());
|
||||||
|
} else {
|
||||||
|
ptextindex=0;
|
||||||
|
ptextdirection=1;
|
||||||
|
ptextmillis=0;
|
||||||
|
ptext=val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mode='z';
|
||||||
|
val="";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(millis()>timemillis+timertemp)
|
||||||
|
{
|
||||||
|
timemillis=millis();
|
||||||
|
float temperature = 0;
|
||||||
|
float humidity = 0;
|
||||||
|
int humidity2 = 0;
|
||||||
|
int err = SimpleDHTErrSuccess;
|
||||||
|
if ((err = dht22.read2(PIN_DHT22, &temperature, &humidity, NULL)) == SimpleDHTErrSuccess) {
|
||||||
|
humidity2=round(humidity);
|
||||||
|
/* Serial.print("t ");
|
||||||
|
Serial.print(timemillis);
|
||||||
|
Serial.print(' ');
|
||||||
|
Serial.print(temperature);
|
||||||
|
Serial.print(' ');
|
||||||
|
Serial.print(humidity);
|
||||||
|
Serial.print(' ');
|
||||||
|
Serial.print(humidity2);
|
||||||
|
Serial.print(' ');
|
||||||
|
Serial.println(millis());*/
|
||||||
|
if(oldtemperature!=temperature) { Serial.print("t "); Serial.println(temperature); }
|
||||||
|
if(oldhumidity!=humidity2) { Serial.print("h "); Serial.println(humidity2); }
|
||||||
|
oldtemperature=temperature;
|
||||||
|
oldhumidity=humidity2;
|
||||||
|
//} else {
|
||||||
|
// Serial.print("Read DHT22 failed, err="); Serial.println(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(millis()>timemillislux+timerlux)
|
||||||
|
{
|
||||||
|
timemillislux=millis();
|
||||||
|
uint16_t lux = lightMeter.readLightLevel();
|
||||||
|
if(lux!=oldlux)
|
||||||
|
{
|
||||||
|
oldlux=lux;
|
||||||
|
Serial.print("x "); Serial.println(lux);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*if(cmindex != -1)
|
||||||
|
{
|
||||||
|
if(millis()-cmmillis > 200)
|
||||||
|
{
|
||||||
|
cmmillis = millis();
|
||||||
|
noTone(PIN_BUZZER);
|
||||||
|
if(cmmusic[cmindex] != 0)
|
||||||
|
{
|
||||||
|
tone(PIN_BUZZER, cmmusic[cmindex]);
|
||||||
|
}
|
||||||
|
cmindex++;
|
||||||
|
if(cmindex == sizeof(cmmusic)/sizeof(cmmusic[0])) { cmindex = 0; }
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
while( !rtttl::done() )
|
||||||
|
{
|
||||||
|
rtttl::play();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ptextstate==true and ptextindex != -1 and millis()-ptextmillis > 1500)
|
||||||
|
{
|
||||||
|
ptextmillis=millis();
|
||||||
|
display.sendString(ptext.substring(ptextindex, ptextindex+8).c_str());
|
||||||
|
if((unsigned)(ptextindex+ptextdirection+8)>ptext.length())
|
||||||
|
{
|
||||||
|
ptextdirection=-1;
|
||||||
|
ptextindex=ptextindex-1;
|
||||||
|
} else if(ptextindex+ptextdirection == -1) {
|
||||||
|
ptextdirection=1;
|
||||||
|
ptextindex=ptextindex+1;
|
||||||
|
} else {
|
||||||
|
ptextindex=ptextindex+ptextdirection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue