Graynomad:
And finally a less flexible version with no pin initialisation (not required for inputs)
char * strings[] = {"CODE1\r","CODE2\r","CODE3\r","CODE4\r"};
int main(void) {
init();
Serial.begin(9600);
while (1) {
for (int i = 10; i < 14; i++) {
if (digitalRead(i)) {
Serial.print(strings[i-10]);
delay(1000);
}
}
}
}
Is 2268 bytes.
If you take out the references to "Serial" and compile for Tiny85 (I don't have Tiny2313 installed) you get 666 bytes.
Conclusion: The Serial library is incredibly bloated.
What else can we do? Let's start by substituting "_delay_ms()" for "delay()" like this:
#include <util/delay.h>
int main(void) {
//init(); // Not needed if we don't use delay()
//Serial.begin(9600);
while (1) {
for (int i = 10; i < 14; i++) {
if (digitalRead(i)) {
//Serial.print(strings[i-10]);
_delay_ms(1000);
}
}
}
}
Now it's only 282 bytes instead of 666.
We could return to the original style and use "digitalReadFast()" instead of "digitalRead()":
#include <util/delay.h>
/*--------------------------------------------------
Inline copy of digitalwritefast.h for Tiny85
--------------------------------------------------*/
// Standard Arduino Pins
#define digitalPinToPortReg(P) &PORTB
#define digitalPinToDDRReg(P) &DDRB
#define digitalPinToPINReg(P) &PINB
#define digitalPinToBit(P) P
#define pinModeFast(P, V) \
if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \
bitWrite(*digitalPinToDDRReg(P), digitalPinToBit(P), (V)); \
} else { \
pinMode((P), (V)); \
}
#define digitalWriteFast2(P, V) \
if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \
bitWrite(*digitalPinToPortReg(P), digitalPinToBit(P), (V)); \
} else { \
digitalWrite((P), (V)); \
}
#define digitalReadFast2(P ) \
((__builtin_constant_p(P) ) \
? (byte)bitRead(*digitalPinToPINReg(P), digitalPinToBit(P)) \
: (byte)digitalRead(P) \
)
int main(void) {
while (1) {
if (digitalReadFast2(0)) {
_delay_ms(1000);
}
if (digitalReadFast2(1)) {
_delay_ms(1000);
}
if (digitalReadFast2(2)) {
_delay_ms(1000);
}
if (digitalReadFast2(3)) {
_delay_ms(1000);
}
}
}
186 bytes instead of 282, not too bad.
Let's put all the messages back in (nb. using flash memory instead of RAM):
#include <util/delay.h>
/*--------------------------------------------------
Inline copy of digitalwritefast.h for Tiny85
--------------------------------------------------*/
// Standard Arduino Pins
#define digitalPinToPortReg(P) &PORTB
#define digitalPinToDDRReg(P) &DDRB
#define digitalPinToPINReg(P) &PINB
#define digitalPinToBit(P) P
#define pinModeFast(P, V) \
if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \
bitWrite(*digitalPinToDDRReg(P), digitalPinToBit(P), (V)); \
} else { \
pinMode((P), (V)); \
}
#define digitalWriteFast2(P, V) \
if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \
bitWrite(*digitalPinToPortReg(P), digitalPinToBit(P), (V)); \
} else { \
digitalWrite((P), (V)); \
}
#define digitalReadFast2(P ) \
((__builtin_constant_p(P) ) \
? (byte)bitRead(*digitalPinToPINReg(P), digitalPinToBit(P)) \
: (byte)digitalRead(P) \
)
void writeChar(char c)
{
// We need to send 'c' via the Tiny2313 serial port
USIDR = c; // This is for Tiny85 :-)
}
void msg(const __FlashStringHelper *s)
{
const prog_char *m = (prog_char*)s;
char c = pgm_read_byte(m);
while (c) {
writeChar(c);
c = pgm_read_byte(++m);
}
}
int main(void) {
while (1) {
if (digitalReadFast2(0)) {
msg(F("CODE1"));
_delay_ms(1000);
}
if (digitalReadFast2(1)) {
msg(F("CODE1"));
_delay_ms(1000);
}
if (digitalReadFast2(2)) {
msg(F("CODE1"));
_delay_ms(1000);
}
if (digitalReadFast2(3)) {
msg(F("CODE1"));
_delay_ms(1000);
}
}
}
306 bytes.... almost an order of magnitude less than the original 2268 bytes.
We'll need another 50 bytes or so to get it fully working on a Tiny2313 but it'll be way smaller than the BASIC version.