This is what I have now. An experiment with two arduino nanos. One has DS1307 clock and bme280 sensor. The other has 4 displays and uses pins d2-d13 for those. Pins d0-d1 are for serial connection between the nanos.
The reason for two nanos is that reading the sensor and converting the time and sensor readings to displays format takes so much time that displays blink off when calculating those.
Now the first nano handles clock and sensor reading and for converting the numbers to display format. And the second is only checking for incoming serial data and showing it on displays. Because the time is displayed only in minutes so are the displays also updated only once in a minute. When minute changes in the first nanos clock it will send new display string to the other nano.
What I want, is to free digital io pins from the second nano because now they are all reserved for the displays. I want two pins free so I can change the wired serial connection to bluetooth connection. So I can keep the sensor (and the clock) out on the balcony and the displays in the house.
Code for the display nano is
/*
* uses 4 displays to show time, temperature, air pressure and humidity
* program reads display formatted readings from the serial port send here by another nano
*
* Scion Riverson 2018
*/
// 1. display pins
int SCLK_1 = 4;
int RCLK_1 = 3;
int DIO_1 = 2;
// 2. display pins
int SCLK_2 = 7;
int RCLK_2 = 6;
int DIO_2 = 5;
// 3. display pins
int SCLK_3 = 10;
int RCLK_3 = 9;
int DIO_3 = 8;
// 4. display pins
int SCLK_4 = 13;
int RCLK_4 = 12;
int DIO_4 = 11;
// Each port represents one digit in the led display.
// Ports in the array are in the order as the digits are in the display, from left to right
unsigned char ports[4] = {0b1000, 0b0100, 0b0010, 0b0001};
// Set initial display strings for the displays.
// Each display shows first it's own ordinal number when powered up
// 1. display's string in led display format
unsigned char luku_1[4] = {0xF9, 0xF9, 0xF9, 0xF9}; // 1111
// 2. display's string in led display format
unsigned char luku_2[4] = {0xA4, 0xA4, 0xA4, 0xA4}; // 2222
// 3. display's string in led display format
unsigned char luku_3[4] = {0xB0, 0xB0, 0xB0, 0xB0}; // 3333
// 4. display's string in led display format
unsigned char luku_4[4] = {0x99, 0x99, 0x99, 0x99}; // 4444
// buffer where to get the readings from the serial port
unsigned char bufStr[16];
void setup() {
// open serial port
Serial.begin(9600);
//initialize 1. displays pins
pinMode(SCLK_1, OUTPUT);
pinMode(RCLK_1, OUTPUT);
pinMode(DIO_1, OUTPUT);
//initialize 2. displays pins
pinMode(SCLK_2, OUTPUT);
pinMode(RCLK_2, OUTPUT);
pinMode(DIO_2, OUTPUT);
//initialize 3. displays pins
pinMode(SCLK_3, OUTPUT);
pinMode(RCLK_3, OUTPUT);
pinMode(DIO_3, OUTPUT);
//initialize 4. displays pins
pinMode(SCLK_4, OUTPUT);
pinMode(RCLK_4, OUTPUT);
pinMode(DIO_4, OUTPUT);
} //setup()
void loop() {
// get readings from the serial port and split retrieved string to display strings
if (Serial.available() > 0) {
Serial.readBytes(bufStr, 16);
for (int i = 0; i < 4; i++) {
luku_1[i] = bufStr[i];
}
for (int i = 4; i < 8; i++) {
luku_2[i - 4] = bufStr[i];
}
for (int i = 8; i < 12; i++) {
luku_3[i - 8] = bufStr[i];
}
for (int i = 12; i < 16; i++) {
luku_4[i - 12] = bufStr[i];
}
}
// display retrieved strings
dspStr_1(luku_1);
dspStr_2(luku_2);
dspStr_3(luku_3);
dspStr_4(luku_4);
} //loop()
/*
1. display routines
*/
// sends a byte to displays controller bit by bit
void send_1(unsigned char X)
{
for (int i = 8; i >= 1; i--)
{
if (X & 0x80)
{
digitalWrite(DIO_1, HIGH);
}
else
{
digitalWrite(DIO_1, LOW);
}
X <<= 1;
digitalWrite(SCLK_1, LOW);
digitalWrite(SCLK_1, HIGH);
}
}
// you must send 2 bytes to the led display controller
// first byte for the character to be displayed
// second byte to choose the port which defines which one of four led digits should show it
void sendDigit_1(unsigned char X, unsigned char port)
{
send_1(X);
send_1(port);
digitalWrite(RCLK_1, LOW);
digitalWrite(RCLK_1, HIGH);
}
// send led format string to display controller
// this one is to show time so it adds a desimalpoint to the second digit
void dspStr_1(unsigned char[]) {
luku_1[1] = luku_1[1] - 0x80; //add desimalpoint to second digit
for (int i = 0; i < 4; i++) {
sendDigit_1(luku_1[i], ports[i]);
}
sendDigit_1(0xFF, 3); //Have to turn the last character off, otherwise it burns brighter then others
}
/*
2. display routines
all the same things are here as are in 1. displays routines
except desimalpoint is in the 3. digit to show temperature with one desimal
*/
void send_2(unsigned char X)
{
for (int i = 8; i >= 1; i--)
{
if (X & 0x80)
{
digitalWrite(DIO_2, HIGH);
}
else
{
digitalWrite(DIO_2, LOW);
}
X <<= 1;
digitalWrite(SCLK_2, LOW);
digitalWrite(SCLK_2, HIGH);
}
}
void sendDigit_2(unsigned char X, unsigned char port)
{
send_2(X);
send_2(port);
digitalWrite(RCLK_2, LOW);
digitalWrite(RCLK_2, HIGH);
}
void dspStr_2(unsigned char[]) {
luku_2[2] = luku_2[2] - 0x80; //desimalpoint for the temperature
for (int i = 0; i < 4; i++) {
sendDigit_2(luku_2[i], ports[i]);
}
sendDigit_2(0xFF, 3); //Have to turn the last character off, otherwise it burns brighter then others
}
/*
3. display routines
All the same things are here as are in 1. and 2. displays routines
except there is no desimalpoint. Same goes with the 4. display.
*/
void send_3(unsigned char X)
{
for (int i = 8; i >= 1; i--)
{
if (X & 0x80)
{
digitalWrite(DIO_3, HIGH);
}
else
{
digitalWrite(DIO_3, LOW);
}
X <<= 1;
digitalWrite(SCLK_3, LOW);
digitalWrite(SCLK_3, HIGH);
}
}
void sendDigit_3(unsigned char X, unsigned char port)
{
send_3(X);
send_3(port);
digitalWrite(RCLK_3, LOW);
digitalWrite(RCLK_3, HIGH);
}
void dspStr_3(unsigned char[]) {
for (int i = 0; i < 4; i++) {
sendDigit_3(luku_3[i], ports[i]);
}
sendDigit_3(0xFF, 3); //Have to turn the last character off, otherwise it burns brighter then others
}
/*
4. display routines
*/
void send_4(unsigned char X)
{
for (int i = 8; i >= 1; i--)
{
if (X & 0x80)
{
digitalWrite(DIO_4, HIGH);
}
else
{
digitalWrite(DIO_4, LOW);
}
X <<= 1;
digitalWrite(SCLK_4, LOW);
digitalWrite(SCLK_4, HIGH);
}
}
void sendDigit_4(unsigned char X, unsigned char port)
{
send_4(X);
send_4(port);
digitalWrite(RCLK_4, LOW);
digitalWrite(RCLK_4, HIGH);
}
void dspStr_4(unsigned char[]) {
for (int i = 0; i < 4; i++) {
sendDigit_4(luku_4[i], ports[i]);
}
sendDigit_4(0xFF, 3); //Have to turn the last character off, otherwise it burns brighter then others
}
Most of the essential parts of the code are borrowed from V. Kostarev's TM74HC595Display library.
I'm not a great programming wizard so please don't be too cruel when judging that code.