I do have the installation files. I have 1.6.3, 1.6.7, 1.6.11 and 1.6.12 exe files. However there were so many libraries and versions that I downloaded that were not part of the install. Maybe I'll work it out somehow.
Install the latest IDE, open your sketches (.ino) and try to compile. The compilier will complain about the missing libs. Install the libs and try again. You don't need to use and old IDE.
In any case you should post your code here and we can advise on what libs may be needed.
It's the little things also like brownout setting, lowers to 1.8V, changed to 1mhz, etc, then the correct libraries. I then need to make the receiver as well to test it. It's daunting for me.
Re the code, it's pretty long but I put a "stack" of notes in case the next soccer club volunteer took this on and had to maintain it - but it's now landed back in my lap!
By the way, the reason for all this... There are 2 scoreboards. Each is on a different receiver frequency. One works well. The other had the hand held remote break and has "always" had a bit of difficulty getting going and transmitting from just half way across the pitch. Now that it doesn't work, I'm stumped. Hence the reason I thought I'd just make a new set of boards and see if I could fix it. But quite a daunting task...
/******************************************************************************
This transmitter is based on an Arduino Mini Pro 3.3V 8MHz Atmega328P processor
Power supply is 2 x AA alkaline batteries (as these are readily available)
The transmitter is an nRF24L01+ which operates on a voltage between 1.8V and 3.3V
The processor has been programmed to also operate on a voltage between 1.9V and 3.3V
To minimise power use, and extend battery life, the following has been done:
1. Avoided using a voltage regulator or step down power supply
2. Power is used directly from 2 x AA, 1.5V batteries
3. After startup, the processor goes to a deep sleep
4. At the same time, the nRF goes into a powerDown mode
5. A keybutton press then runs as an interrupt to wake the proccessor and nRF
6. After processing the press and transmitting, the unit goes back to sleep
7. Action for both a short press and long press has been programmed into the code
8. Current draw measured is:
- 2.26mA during normal operation
- 0.91mA during "wait"
- 0.70uA during deep sleep
9. To attain these low values, the mini pro has:
a. Had the voltage regulator removed
b. Had the power led removed
c. Re-bootloaded with code that turns off brownout
d. Re-bootloaded with code lowers the brownout level to 1.8V
e. MHz dropped to 1MHz
11. Due to the lower base voltage, an led is wired up to blink a green LED once
when a button is pressed to change the score. If voltage is measured as being
under 2.1V, it will blink a red LED three times - warning to change battery
Note, at 1.97V I found the transmitter wouldn't transmit (hence 2V cutoff)
I also found at "myRadio.setPALevel" set to "MIN", min working V = 1.925
Also found that at "MAX" min working V = 2.030
12. The above is based on measuring the internal voltage of the processor
(1.1V). It has also been adjusted according to the "real" internal voltage
13. In order to be able to light up an LED at 2.0V, a "voltage doubler" or
"two stage inverter" is included in the circuitry
This code utlises the libraries: avr/sleep.h , avr/power.h , SPI.h and RF24.h
This code transmits data from one nRF24L01 to another. The input on the
transmitter is done via a 3 column x 4 row keypad. When a button is pressed on the
keypad, a "~" is first sent, followed by the number, followed by a "!". Each
key press is an ascii (such as ascii "49" for key 1). This is then stored to a variable
as "character" (i.e. A, or B, etc) which also have an ascii character. This is the ascii
that is sent to the receiver. Key presses sent in this code are as follows:
0 = Siren off
1 = Increment home score by 1
2 = Nil
3 - Increment away score by 1
4 = Decrease home score by 1
5 = start / pause / resume
6 = Decrease away score by 1
7 = Nil
8 = Turn displays back on (if off)
9 = Nil
# = Nil
* = A prefix to allow for setting the timer
# = used in cancelling the press combinations
0 (hold) = siren set to play when time reached
1 (hold) = reset home score to 00
2 (hold) = runs a test display of 8's on each "set" of digits
3 (hold) = reset away score to 00
5 (hold) = reset timer to 00:00 ready to start
8 (hold) = turn off all the displays
# (hold) = reset Date_Time (held down for 2 seconds)
If the scoreboard is in Date_Time reset mode, the following keypad actions happen:
2 = increment up the flashing digit value
4 = move to the next digit left to set it
6 = move to the next digit right to set it
8 = increment down the flashing digit value
Note:
The month is displayed on the home score (bottom left of the board)
The year is displayed in the timer (middle of the board)
The date is displayed on the away score (bottom right of the board)
The current time is displayed in the usual spot (top right of the board)
The temperature digits are temporarily turned off
To accept the date_time changes, again hold down "#" for 2 seconds
Start with radios about 4 feet apart.
nRF2401 setup:
GND
VCC - to 3.3V
CE - to Arduino pin 9
CSN - to Arduino pin 10
SCK - to Arduino pin 13
MOSI - to Arduino pin 11
MISO - to Arduino pin 12
IRQ - Not used
4 x 3 keypad: Rows = pins A0, A1, A2, A3. Columns = pins 4, 5, 6
*/
//**********************************************************
#include <avr/sleep.h>
#include <avr/power.h>
#include <SPI.h> // Comes with Arduino IDE
#include "RF24.h" // https://github.com/TMRh20/RF24
// variable for keypad -----------------------
unsigned long currentMillis = 0; // used in pushbutton timing
unsigned long previousMillis = 0; // used in pushbutton timing
unsigned long pressStartTime = 0; // used in pushbutton timing
unsigned long buttonPressLong = 1000; // min time required for long keypad press
const byte debounceTime = 0; // allow time for button to go LOW
enum buttonPress { // used to mark button press duration
up,
down,
shortPress,
longPress,
};
int buttonPress = up; // default - no press
const int numRows = 4; // number of rows in the keypad
const int numCols = 3; // number of columns
byte r;
char key;
// array used to nominate pins used for the rows and columns
const int rowPins[numRows] = {14, 15, 16, 17}; // rows 0, 1, 2 and 3
const int colPins[numCols] = {4, 5, 6}; // columns 1, 2 and 2
// Map of the keys on the keypad
const char keymap[numRows][numCols] = {
{ '1', '2', '3' },
{ '4', '5', '6' },
{ '7', '8', '9' },
{ '*', '0', '#' }
};
/**************************************
Pin change interrupts for info only...
Pin Mask / Flag / Enable
D0 PCINT16 (PCMSK2 / PCIF2 / PCIE2)
D1 PCINT17 (PCMSK2 / PCIF2 / PCIE2)
D2 PCINT18 (PCMSK2 / PCIF2 / PCIE2)
D3 PCINT19 (PCMSK2 / PCIF2 / PCIE2)
D4 PCINT20 (PCMSK2 / PCIF2 / PCIE2)
D5 PCINT21 (PCMSK2 / PCIF2 / PCIE2)
D6 PCINT22 (PCMSK2 / PCIF2 / PCIE2)
D7 PCINT23 (PCMSK2 / PCIF2 / PCIE2)
D8 PCINT0 (PCMSK0 / PCIF0 / PCIE0)
D9 PCINT1 (PCMSK0 / PCIF0 / PCIE0)
D10 PCINT2 (PCMSK0 / PCIF0 / PCIE0)
D11 PCINT3 (PCMSK0 / PCIF0 / PCIE0)
D12 PCINT4 (PCMSK0 / PCIF0 / PCIE0)
D13 PCINT5 (PCMSK0 / PCIF0 / PCIE0)
A0 PCINT8 (PCMSK1 / PCIF1 / PCIE1)
A1 PCINT9 (PCMSK1 / PCIF1 / PCIE1)
A2 PCINT10 (PCMSK1 / PCIF1 / PCIE1)
A3 PCINT11 (PCMSK1 / PCIF1 / PCIE1)
A4 PCINT12 (PCMSK1 / PCIF1 / PCIE1)
A5 PCINT13 (PCMSK1 / PCIF1 / PCIE1)
***************************************
*/
// turn off interrupts until we are ready
ISR (PCINT0_vect) {
PCICR = 0; // cancel pin change interrupts for D8 to D13
} // end of ISR (PCINT0_vect)
ISR (PCINT1_vect) {
PCICR = 0; // cancel pin change interrupts for A0 to A5
} // end of ISR (PCINT1_vect)
ISR (PCINT2_vect) {
PCICR = 0; // cancel pin change interrupts for D0 to D07
} // end of ISR (PCINT2_vect)
// ADC control Status Register A.
byte old_ADCSRA;
// variable for low battery warning-----------
byte ledPin = 2; // to RGB LED common (anode)
byte ledPinGreen = 7; // to RGB LED green pin - battery voltage above 2.1V
byte ledPinRed = 8; // to RGB LED red pin - low battery warning
unsigned long ledCurrentMillis = 0; // used for LED flash timing
const int ledFlashTime = 50; // used for the above LEDs - 50
float frequencyGreenLED; // used to maintain current to green LED
float frequencyRedLED; // used to maintain current to red LED
float result; // variable to sort the reference voltage
// Transmit data is sent with a ~ at the start and ! at the end to verify the data is valid
byte CmdStart = '~'; // ASCII value = 126
byte CmdEnd = '!'; // ASCII value = 33
byte FlagKeyN = 0; // flag the keypad number
byte FlagTimer = 0; // flag used to set the count down time
byte timerToggle = 0; // variable used to toggle the timer from start to pause and reset
// When one of the following is transmitted, it is so as an ascii character
// On the receiver program, the ascii is read and program executed as listed in the "case" list
byte Zero = 'A'; // variable used to send the number 0 (ASCII of A = 65)
byte One = 'B'; // variable used to send the number 1 (ASCII of B = 66)
byte Two = 'C'; // variable used to send the number 2 (ASCII of C = 67)
byte Three = 'D'; // variable used to send the number 3 (ASCII of D = 68)
byte Four = 'E'; // variable used to send the number 4 (ASCII of E = 69)
byte Five = 'F'; // variable used to send the number 5 (ASCII of F = 70)
byte Six = 'G'; // variable used to send the number 6 (ASCII of G = 71)
byte Seven = 'H'; // variable used to send the number 7 (ASCII of H = 72)
byte Eight = 'I'; // variable used to send the number 8 (ASCII of I = 73)
byte Nine = 'J'; // variable used to send the number 9 (ASCII of J = 74)
byte Hash = 'K'; // variable used to send a "hash" (ASCII of K = 75)
byte Asterix = 'L'; // variable used to send an asterix (ASCII of L = 76)
byte sirenActive = 'M'; // "0" button held - variable used to activate the siren (ASCII of M = 77)
byte homeReset = 'N'; // "1" button held - variable used to reset the home score (ASCII of N = 78)
byte awayReset = 'O'; // "3" button held - variable used to reset the away score (ACII of O = 79)
byte displayOff = 'P'; // "8" button held - variable used to turn off the led displays (ASCII of P = 80)
byte resetTimer = 'Q'; // "5" button held - variable used to reset the timer to start (ASCII of Q = 81)
byte testDigits = 'R'; // "2" button held - variable used to test each set of digits (ASCII of R = 82)
byte resetTimeDate = 'S';// "#" button held - variable used to set the time and date (ASCII of S = 83)
int number;
// (Create an instance of a radio, specifying the CE and CS pins. )
RF24 myRadio (9, 10); // "myRadio" is the identifier you will use in following methods
byte addresses[][6] = {"1Node"}; // Create address for 1 pipe.
//**********************************************************
void setup() {
clock_prescale_set(clock_div_2); // speed conversion due to Mini Pro running at 8MHz for power saving
// clock_prescale_set(clock_div_4); // comment the above and uncomment this line to keep the 4MHz overall clock speed
Serial.begin(9600);
delay(500); // just gives some time for starting the serial monitor
Serial.println(F("RF24/Simple Transmit data Check"));
pinMode(ledPinGreen, OUTPUT); // Sets the digital pin as output
pinMode(ledPinRed, OUTPUT); // Sets the digital pin as output
digitalWrite(ledPinGreen, LOW); // Start with LED off
digitalWrite(ledPinRed, LOW); // Start with LED off
// pin change interrupt masks (see above list)
PCMSK1 |= bit (PCINT8); // pin 14
PCMSK1 |= bit (PCINT9); // pin 15
PCMSK1 |= bit (PCINT10); // pin 16
PCMSK1 |= bit (PCINT11); // pin 17
old_ADCSRA = ADCSRA; // Only necessary if you want to reenable the ADC at some point.
ADCSRA = 0; // Turn off ADC power
ACSR |= _BV(ACD); // turn off analog comparator.
power_all_disable();
power_timer2_enable();
power_timer0_enable(); // if you want to use mills(), micros(), or delay().
power_usart0_enable(); // if you want to use Serial.
power_spi_enable(); // for the nRF24 module.
for (byte row = 0; row < numRows; row++) {
pinMode (rowPins[row], INPUT); // this sets the row pins as inputs
digitalWrite (rowPins[row], HIGH); // set high
} // end for
for (byte column = 0; column < numCols; column++) {
pinMode (colPins[column], OUTPUT); // this sets the column pins as outputs
digitalWrite (colPins[column], HIGH);// set high
} // end for
myRadio.begin(); // Start up the physical nRF24L01 Radio
myRadio.setChannel(108); // Above most Wifi Channels (note 116 = remote 1 and 108 = remote 2)
// PA level can be MIN, HIGH or MAX. RF24_PA_MAX is default.
// myRadio.setPALevel(RF24_PA_MIN); // Uncomment for less power
myRadio.setPALevel(RF24_PA_MAX); // Uncomment for more power
myRadio.openWritingPipe( addresses[0]); // Use the first entry in array 'addresses' (Only 1 right now)
// look up how to set retries time
// ditto for set low data rate to save power
delay(1000);
} // end void setup
//*****************************************
void loop() {
if (buttonPress == up) {
goToSleep();
}
char key = getKey();
checkDuration ();
shortDown();
longDown();
} // end void loop
//*****************************************
// returns with the key pressed, or 0 if no key is pressed
char getKey() {
if ( buttonPress == up) {
key = 0; // 0 indicates no key pressed
for (byte column = 0; column < numCols; column++) {
digitalWrite(colPins[column], LOW); // Activate the current column.
for (byte row = 0; row < numRows; row++) { // Scan all rows for a key press.
if (digitalRead(rowPins[row]) == LOW && millis() - currentMillis > debounceTime) { // Is a key pressed?
previousMillis = currentMillis;
pressStartTime = millis();
read_Vcc();
flash();
buttonPress = down;
key = keymap[row][column]; // Remember which key was pressed.
r = row;
return key;
} // end if
} // end for
digitalWrite(colPins[column], HIGH);
} // end for
} // end if
} // end getKey
//*****************************************
void checkDuration () {
currentMillis = millis();
if (buttonPress == down) {
// if button has been released and debounce time expired, do the following
if (digitalRead(rowPins[r]) == HIGH && currentMillis - previousMillis > debounceTime) {
previousMillis = currentMillis;
buttonPress = shortPress;
currentMillis = millis();
return; // exit this function as key has been pressed and released
} // end if
// if button is still pressed, and long press time expired, do the following
if (digitalRead(rowPins[r]) == LOW && currentMillis - pressStartTime > buttonPressLong) {
previousMillis = currentMillis;
buttonPress = longPress;
} // end if
} // end if
} // end void checkDuration
//*****************************************
void shortDown() {
// execute SHORT keypress action
if (buttonPress == shortPress) {
myRadio.powerUp();
FlagKeyN = key; // Set the FlagKeyN variable to the currently pressed key number
delay(10); // this allows the radio to fully wake up before sending the signal
switch (FlagKeyN) {
case 48:
// keypad 0 pressed
SendCommand(Zero); // this transmits the value 'A' in ascii = 65
break;
case 49:
// keypad 1 pressed
SendCommand(One); // this transmits the value 'B' in ascii = 66
break;
case 50:
// keypad 2 pressed
SendCommand(Two); // this transmits the value 'C' in ascii = 67
break;
case 51:
// keypad 3 pressed
SendCommand(Three); // this transmits the value 'D' in ascii = 68
break;
case 52:
// keypad 4 pressed
SendCommand(Four); // this transmits the value 'E' in ascii = 69
break;
case 53:
// keypad 5 pressed
SendCommand(Five); // this transmits the value 'F' in ascii = 70
break;
case 54:
// keypad 6 pressed
SendCommand(Six); // this transmits the value 'G' in ascii = 71
break;
case 55:
// keypad 7 pressed
SendCommand(Seven); // this transmits the value 'H' in ascii = 72
break;
case 56:
// keypad 8 pressed
SendCommand(Eight); // this transmits the value 'I' in ascii = 73
break;
case 57:
// keypad 9 pressed
SendCommand(Nine); // this transmits the value 'J' in ascii = 74
break;
case 35:
// keypad * pressed
SendCommand(Hash); // this transmits the value 'K' in ascii = 75
break;
case 42:
// keypad # pressed
SendCommand(Asterix); // this transmits the value 'L' in ascii = 76
break;
} // end switch
// serial print statements below simply used for checking
printKey ();
for (byte column = 0; column < numCols; column++) {
digitalWrite(colPins[column], HIGH);
} // end for
buttonPress = up;
} // end if SHORT keypress
} // end void shortDown
//*****************************************
void longDown() {
// execute LONG keypress action
if (buttonPress == longPress) {
myRadio.powerUp();
FlagKeyN = key; // Set the FlagKeyN variable to the currently pressed key number
delay(10); // this allows the radio to fully wake up before sending the signal
switch (FlagKeyN) {
case 48:
// keypad 0 held pressed
SendCommand(sirenActive); // this transmits the value 'M' in ascii = 77
break;
case 49:
// keypad 1 held pressed to reset home score to 00
SendCommand(homeReset); // this transmits the value 'N' in ascii = 78
break;
case 51:
// keypad 3 held pressed to reset away score to 00
SendCommand(awayReset); // this transmits the value 'O' in ascii = 79
break;
case 56:
// keypad 8 held pressed to turn off led displays
SendCommand(displayOff); // this transmits the value 'P' in ascii = 80
break;
case 53:
// keypad 5 held pressed to reset home time to 00
SendCommand(resetTimer); // this transmits the value 'Q' in ascii = 81
break;
case 50:
// keypad 2 held pressed to test each set of digits
SendCommand(testDigits); // this transmits the value 'R' in ascii = 82
break;
case 35:
// keypad # held pressed to change the current time and date
SendCommand(resetTimeDate); // this transmits the value 'S' in ascii = 83
break;
} // end switch
printKey ();
while (digitalRead(rowPins[r]) == LOW) {
power_nap();
; // just wait until button is released
} // end while
for (byte column = 0; column < numCols; column++) {
digitalWrite(colPins[column], HIGH);
} // end for
buttonPress = up;
} // end if LONG keypress
} // end void longDown
//**********************************************************
// function below used for checking only
void printKey () {
// serial print statements below simply used for checking
Serial.print(". i = ");
Serial.print(FlagKeyN);
Serial.print(" Key no. ");
Serial.print(key);
Serial.println(" pressed.");
} // end void
//**********************************************************
// Send Command via Radio
void SendCommand(byte KeyCmd) {
myRadio.write(&CmdStart, sizeof(CmdStart));
myRadio.write(&KeyCmd, sizeof(KeyCmd));
myRadio.write(&CmdEnd, sizeof(CmdEnd));
Serial.print(F("Command Sent = "));
Serial.print(KeyCmd);
} // end void SendCommand
//**********************************************************
void read_Vcc() {
// Re-enable ADC clock and power.
power_adc_enable();
ADCSRA = old_ADCSRA;
// Set external reference and
// bandgap input channel.
ADMUX = 1 << REFS0 | 14 << MUX0;
// perform first dummy conversion.
// Don't care about this result, just
// let's the bandgap settle after being turned on.
ADCSRA |= _BV(ADSC);
while (bit_is_set(ADCSRA, ADSC));
delayMicroseconds(150);
// The real one, keep this result.
ADCSRA |= _BV(ADSC);
while (bit_is_set(ADCSRA, ADSC));
result;
result = ADC;
// Disable ADC.
ADCSRA = 0;
power_adc_disable();
// Calculate reference (battery) voltage based on 1100 mV bandgap input.
// Calibrate the 1100 value to match the real bandgap value, or use an accurate
// external reference.
// return 1100*1024L / (result);
result = 1127419UL / (1000 * result); // Back-calculate Vcc in mV
// I added the 1000 above so the printout shows it in the correct decimal format
// Serial.print("Battery voltage = ");
// Serial.print(result, 3); // display to 3 decimal places
// Serial.println("V");
// During testing using 3.3V supply, limit the result
if (result > 3.0) {
result = 3.0;
}
// Now let's convert the frequency to suit the current voltage
// For green, is a reciprical function y = k/x (approx. y = 1000(V-1.5) )
frequencyGreenLED = (1000 / ( result - 1.5));
// For red, is a also a reciprical, but in the low voltage almost linear y=-2033x+5413
frequencyRedLED = ( (-2033 * result) + 5413 );
// Serial.print("FrequencyLED = ");
// Serial.println(frequencyLED);
} // end read_Vcc
//********************************************************
void goToSleep () {
byte i;
// set up to detect a keypress
for (i = 0; i < numCols; i++) {
pinMode (colPins [i], OUTPUT);
digitalWrite (colPins [i], LOW); // columns low
} // end for
for (i = 0; i < numRows; i++) {
pinMode (rowPins [i], INPUT);
digitalWrite (rowPins [i], HIGH); // rows high (pull-up)
} // end for
// now check no pins pressed (otherwise we wake on a key release)
for (i = 0; i < numRows; i++) {
if (digitalRead (rowPins [i]) == LOW) {
for (byte column = 0; column < numCols; column++) {
digitalWrite(colPins[column], HIGH);
} // end for
return;
} // end if
} // end for
// Serial.println("Going to sleep now...");
// Serial.println("Zzzzzzzzz");
myRadio.powerDown(); // this should sleep the nRF to save power
// at this point, pressing a key should connect the high in the row to the
// to the low in the column and trigger a pin change
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
Serial.flush();
cli();
sleep_enable();
PCIFR |= bit (PCIF0) | bit (PCIF1) | bit (PCIF2); // clear any outstanding interrupts
PCICR |= bit (PCIE0) | bit (PCIE1) | bit (PCIE2); // enable pin change interrupts
sleep_bod_disable();
sei();
sleep_cpu ();
// cancel sleep as a precaution
sleep_disable();
// put keypad pins back how they are expected to be
for (byte column = 0; column < numCols; column++) {
digitalWrite(colPins[column], HIGH);
} // end for
currentMillis = millis();
// Serial.println("Waking up now?");
} // end of goToSleep
//**********************************************************
void flash() {
ledCurrentMillis = millis();
if (result > 2.100) {
// voltage is OK so lets single flash the green LED
Serial.println("So since voltage is GREATER than 2.100V, blink green LED");
tone(ledPin, frequencyGreenLED);
digitalWrite(ledPinRed, LOW);
digitalWrite(ledPinGreen, HIGH);
while (millis() - ledCurrentMillis < ledFlashTime)
;
digitalWrite(ledPinGreen, LOW);
noTone(ledPin);
} // end if
else {
// voltage is low so lets flash the red LED 3 times
Serial.println("So since voltage is LOWER than 2.100V, blink red LED");
for (byte i = 0; i < 3; i++) {
ledCurrentMillis = millis();
tone(ledPin, frequencyRedLED);
digitalWrite(ledPinGreen, LOW);
digitalWrite(ledPinRed, HIGH);
while (millis() - ledCurrentMillis < ledFlashTime)
;
digitalWrite(ledPinRed, LOW);
noTone(ledPin);
ledCurrentMillis = millis();
while (millis() - ledCurrentMillis < 5 * ledFlashTime)
;
} // end for
} // end else
} // end void flash
//**********************************************************
void power_nap()
{
set_sleep_mode(SLEEP_MODE_IDLE);
cli();
sleep_enable();
sei();
sleep_cpu();
sleep_disable();
}
Well the only lib you need to install is the RF24.
Use the library manager to install it.
@jim-p , I'm not sure if I should start a new thread here under "programming" or continue here.
In the end I couldn't clone so easily, so I tried my old code on a new mini pro. But I'm now stuck on brownout setting.
I started with a fresh empty Arduino Mini, 3.3V, 8MHz.
I ended up loading Arduino 1.8.19, loaded a new "Time-master" library, RF24 and DS3232RTC from memory. There was some coding changes suggested by chatgpt which in the end started to work!
I had to abandon my user made "Low Voltage Mini Pro" bootloader setup with 1.8V brownout setting and 8MHZ (1MHz bootloader). Could get the baud rate working between the receiver program and transmitter.
So I downloaded MiniCore board setup so I could get my 1.8V brownout setting.
I loaded the ArudinoISP to an Uno, then loaded the new bootloader to the Mini Pro. That worked. But now in uploading the sketch, I get an error as follows:
Arduino: 1.8.19 (Windows 10), Board: "ATmega328, Yes (UART0), EEPROM retained, 115200, 328P / 328PA, BOD 2.7V, LTO enabled, External 8 MHz"
Sketch uses 880 bytes (2%) of program storage space. Maximum is 32384 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.
Warning: attempt 1 of 10: not in sync
Warning: attempt 2 of 10: not in sync
Warning: attempt 3 of 10: not in sync
Warning: attempt 4 of 10: not in sync
Warning: attempt 5 of 10: not in sync
Warning: attempt 6 of 10: not in sync
Warning: attempt 7 of 10: not in sync
Warning: attempt 8 of 10: not in sync
Warning: attempt 9 of 10: not in sync
Warning: attempt 10 of 10: not in sync
Warning: programmer is not responding; try -x strict and/or vary -x delay=100
Error: unable to open port COM5 for programmer urclock
Error: unable to open port COM5 for programmer urclock
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
Unfortunately chatgpt isn't as smart as he thinks he is, and is asking me to abandon the 1.8V brownout setting. Any suggestions?
Donβt start a new topic, your problem is basically the same
So you have the Uno programmer disconnected and you are trying to upload via USB using the upload button, is that correct?
Yes, I was trying to upload "blink" to start with.
But I've kept experimenting and found when I changed the baud rate from 115200 to 9600, it uploaded. Infact I found that anywhere between 9600 and 67600 works. So all good so far... Sorry for the inconvenience.
The latest version of Minicore uses a new bootloader called Urboot. Others have had similar problems with that bootloader and solved it by going back to an old version of Minicore that used Optiboot. Version 2.2.2 was the last that used Optiboot.
I see that there are quite a few version in the board manager. Should I removed 3.1.2 and load an earlier version then?
Yes. Remove 3.1.2 close the IDE and reopen it then install 2.2.2
If you burn the bootloader again it will use Optiboot which is probably the bootloader used on your original boards.
Then you will also have the option to select Arduino Pro Mini from the board manager when uploading code.
It might be helpful to future readers if you could provide information on what you tried to do, and what went wrong, in the cloning process.
If you still have an arduino_as_ISP setup, you can use AVRDudess to change the BOD voltage. It's just changing a fuse byte value.
I've never been able to use 115200 on an 8MHz Pro Mini. It's just not reliable. But 57600 works ok.
@ShermanP , in the end I didnt end up cloning.
I was not confident in using AVRDudess in case I stuffed up my original transmitter. So instead I started from scratch using old code and a new mini.
Connecting to my existing mini pro on the circuit board with an NRF24L01 as well as some discrete components turned out to be problematic. Even loading bootloader again. So simply started again on a new mini pro.
I got it to talk to the receiver, but now I've stuffed up my NFR due to mis wiring, so I'll have to wait for a new unit until I continue. Those nfrs seem to be quite tempramental.
@ShermanP and @jim-p , just a thanks for your advice and suggestions on this cloning.
Today I bit the bullet and thought I'd give cloning a go. It actually went really smoothly. I did the following:
- downloaded and installed AVRDUDESS (what an odd name!) on my laptop
- It self started when installed
- connected my Arduino Uno via USB cable to the laptop
- opened Arduino, uploaded the example file ArduinoISP
- wired the Uno to the Mini pro as follows
- D10 β RESET
- D11 β D11
- D12 β D12
- D13 β D13
- 5V β VCC
- GND β GND
- connected a 47uF cap across GND and reset on the Uno
- in Avrdudess, selected:
- Programmer = "Arduino (Arduino bootloader using STK500)"
- MCU = ATmega328P
- Baud = 19200
- Port = COM5 in my case
- pressed the "detect" button to check the MCU
(came up with "Detected 1e950f = ATmega328P") - all good so far
- In the "flash" section, I noted the hex name and path to save it
- Picked the "read" radio button and "Intel Hex" and format
- Then the "GO" radio button
This read the full flash perfectly first go! - I then connected the new mini pro
- picked the "write" radio button, then the "go" button
This flashed the drive first go. I checked by then trying to upload a new sketch using the same board details using my CH340 and it worked. So I re-flashed again with AVR.
BTW, I tried to then ask chatgpt to convert the hex file to an ino. Hmmmm. Let's just say part of it got converted, and the rest, well, it probably thought the whole thing about changing the score via different button presses didn't really matter much ![]()
Glad you got it working.
It may not matter for the 328P, but I think the correct programmer is arduino_as_isp. See the following excerpt from the .conf file.
#------------------------------------------------------------
# arduino_as_isp
#------------------------------------------------------------
# Not to be confused with arduinoISP, this is the same as `-c stk500v1`
# but treats EEPROM r/w correctly for arduino_as_isp programmers
# See https://docs.arduino.cc/built-in-examples/arduino-isp/ArduinoISP/
# for details.
programmer # arduino_as_isp
id = "arduino_as_isp";
desc = "AVR as programmer with Arduino-as-ISP FW";
type = "stk500";
prog_modes = PM_ISP;
connection_type = serial;
baudrate = 19200;
;
Also, if the old 328P was set to have the 1.8V BOD voltage, then you need to do the same process for the fuses so the new one will also have that voltage.
Set everything up again with the old processor, then in AVRDudess over on the right click "read" next to the "L" fuse, and it should read all three fuses - Low, High, and Extended. Don't mess with the lock bits.
Write down those three values. Then connect up the new processor and do the same. My prediction is that the Low and High fuses will be the same on both, but the Extended fuse will be 0xFE on the old one, and 0xFD on the new one. If that's the case, just change that fuse to 0xFE, and click "Write". Then Read it back again to make sure it took.
If you get something else when reading the fuses, post the results here and we'll try to figure it out.
By the way, per the datasheet, at 8MHz the processor is good down to 2.4V. But it may well work at lower voltage, so 1.8V is a good choice for the 3.3V 8Mhz Pro Mini running directly on a battery. The default is BOD of 2.7V.
Somewhere along the line I did change the fuses. I "think" it was when I loaded minicore. My bootloader burn said:
writing 1 byte efuse ...
verifying efuse memory against 0b11111110.
I believe this is 0b11111110 in binary, which is 0xFE in hex, which is :
1.8V brownout on ATmega328P.
Then when I tried to clone this with avrdudess, from memory, the "read" I did prior to write and clone confirmed this setting. It does now have BOD as 1.8V listed in the board option in ate arduino menu for boards.
As for the "Arduino to ISP" vs "AVRISP mkll", your probably correct. I'll set it back.
By the way, I had quite a hard time uploading altered code from the mini to PC via the CH340. In the end I connected the mini directly to the ch340 pins and bingo. So a cable 350mm long is toooooo long. Lesson for me to learn there.
Also, for a mini pro, my ch340 has 6 pins (DRT, RXD, TXD, VCC, CTS and GND), as well as a toggle for 3V3 and 5V. I don't use CTS, but with the mini pro need DRT. However when I look online, the vast majority of these don't have DRT. Why?




