Hi Forum, regarding In-system Programming (ISP), Wikipedia says: "... the ability ... to be programmed while installed in a complete system ..."
I'm trying to achieve such a "complete system" for ATtiny85 chip with sensors and output devices attached. But it is not clear to me how I can permanently integrate a programmer in this setup where the ATtiny85 is hooked up with most pins already connected. If it is at all possible, please advise on how to proceed, or point me to a project where this has already been used. Any advise on alternatives or further help is highly appriciated.
Background
As a new member in the community, who has a programming background but is novice at electronics, I'm using a Nano based ISP programmer to upload sketches to ATtiny85. I have it working like this.
As my first real project, the details are captured in a series of blog posts , if you're interested.
For the schematics, hope I got this right. Please let me know if there are any flaws. This electronics stuff is all very new to me.
Currently I have to take out the ATtiny85 from the programmer breadboard and move it onto a test breadboard each time the .ino file is changed, to see if it works. Which is cumbersome and, if I understand it correctly, exactly the opposite of in-system programming.
The programmer is connected from Nano ICSP header to the ATtiny85 on pins 4, 5, 6, 7 and 8. And from Nano D10 to ATtiny85 pin 1.
This is the test board for a Blink.ino with LED pin set to 3 (PB3 = physical pin 2 on ATtiny85).
The pins for ICSP are still available. So presumably, I could move the wires over from the programmer and program directly to this test board.
But my question applies to any setup where pins to be used for ICSP are already taken by sensors or output devices. To give an example, this is a current test setup, where I display temperature and humidity readings on an LCD screen. The button is to wake the LCD from screensaver state that kicks in after a minute.
A novice attempt at schematics. Please advise on how to improve.
Pins 5 and 7, to be used for programming the ATtiny85, are already in use. How would I hook up the programmer here when several pins are already taken for the DHT11 and LCD screen? Is it at all possible?
To be complete, the programmer uses Arduino IDE's ArduinoISP.ino from File -> Examples -> 11. ArduinoISP -> ArduinoISP
The temperature/humidity setup uses this code.
// ------------------------------------------------------------
// DHT11 with LCD via TinyLiquidCrystal_I2C
// Read temperature and humidity from DHT11 sensor.
//
// References:
// https://www.make-it.ca/i2c-lcd-display-on-arduino/
// https://create.arduino.cc/projecthub/pibots555/how-to-connect-dht11-sensor-with-arduino-uno-f4d239 (Old links to arduino project hub are broken since recent update)
// https://forum.arduino.cc/t/print-degree-symbol-on-lcd/19073
// https://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#ga060c998e77fb5fc0d3168b3ce8771d42
// ------------------------------------------------------------
// Include the liquid crystal I2C library
#include <TinyLiquidCrystal_I2C.h>
// Include the DHT library
#include "TinyDHT.h"
#define DHTPIN 4
#define DHTTYPE DHT11 // #define DHTTYPE DHT22 // if you have this sensor
#define BUTTONPIN 3
// Create DHT object
DHT dht(DHTPIN, DHTTYPE);
// Set the I2C address to 0x27 for the LCD screen.
// Set to 16 characters and 2 lines. Adjust to (0x27,20,4) for 20x4 LCD
TinyLiquidCrystal_I2C lcd = TinyLiquidCrystal_I2C(0x27,16,2);
const int serialSpeed = 9600;
unsigned long startScrollMillis;
unsigned long startReadMillis;
unsigned long startScreenSaveMillis;
unsigned long screenSaveOffMillis;
boolean screenSaver = false;
unsigned long currentMillis;
const unsigned long lcdScrollDelay = 600;
const unsigned long sensorReadDelay = 10000;
const unsigned long lcdScreenSaveMillis = 60000;
unsigned long diff = 0;
String readString;
String f;
String c;
String h;
String r;
String hic;
String hif;
char buffer[10];
int buttonState = 0;
int previousState = 0;
void setup() {
//Serial.begin(9600);
// Initialize the pin for the button
pinMode(BUTTONPIN, INPUT);
// Initialize the DHT sensor
dht.begin();
// Initialize the LCD display
lcd.init();
// Switch off display for a short while
lcd.noDisplay();
lcd.noBacklight();
delay(2000);
// Turn on the display:
lcd.display();
lcd.backlight();
delay(1000);
// Display startup message
lcd.setCursor(1, 0);
lcd.print("DHT11 LCD I2C");
delay(3000);
lcd.setCursor(1, 1);
lcd.print("fotografeer.nl");
delay(4000);
lcd.clear();
startReadMillis = 0;
startScreenSaveMillis = 0;
}
void loop() {
// Don't read sensor and don't update display if screen saver is on.
// Otherwise wait a while between each read/screen refesh.
currentMillis = millis();
diff = currentMillis - startReadMillis;
if (currentMillis - startReadMillis >= sensorReadDelay && !screenSaver) {
// Read Humidity
float humidity = dht.readHumidity();
h = dtostrf(humidity, 5, 1, buffer);
// Read Temperature in degrees Celsiuse
float celsius = dht.readTemperature();
c = dtostrf(celsius, 5, 1, buffer);
// Read Temperature in degrees Fahrenheit
float fahrenheit = dht.readTemperature(true);
f = dtostrf(fahrenheit, 5, 1, buffer);
// Clear display
lcd.clear();
// Check if any reads failed and exit early (to try again).
if (isnan(humidity) || isnan(celsius) || isnan(fahrenheit)) {
lcd.setCursor(0, 0);
lcd.print("error");
return;
}
// Display Temperatures
lcd.setCursor(0, 0);
lcd.print(c);
lcd.setCursor(5,0);
lcd.print((char)223);
lcd.setCursor(6,0);
lcd.print("C");
lcd.setCursor(9, 0);
lcd.print(f);
lcd.setCursor(14,0);
lcd.print((char)223);
lcd.setCursor(15,0);
lcd.print("F");
// Display Humidity
lcd.setCursor(0, 1);
lcd.print(h);
lcd.setCursor(5,1);
lcd.print("%RH");
startReadMillis = currentMillis;
}
// Get current milliseconds
currentMillis = millis();
// Read current button state (PRESSED/HIGH or RELEASED/LOW)
buttonState = digitalRead(BUTTONPIN);
// If button pressed, turn screensaver off
if (buttonState == HIGH && screenSaver) {
// read the state of the pushbutton value:
lcd.clear();
lcd.backlight();
lcd.display();
screenSaver = false;
screenSaveOffMillis = currentMillis;
}
// Turn LCD screen saver mode on, when screen saver timer has expired
if (currentMillis - screenSaveOffMillis >= lcdScreenSaveMillis && !screenSaver) {
screenSaver = true;
lcd.clear();
lcd.noBacklight();
lcd.noDisplay();
}
}