I have just bought a batch of Nanos advertised as 16MHz clock.
No problem loading code & they run blink, but at quarter speed. Also, I need to set IDE monitor to 1/4 of the figure I specify in the sketch. This is what I wrote:-
On other nano boards monitor is set to 19200 and LED alternates every second, but with this new batch 4800 on the monitor works, and the LED toggles every 4 seconds. I wrote the F_CPU figure on a debug output and that shows as 16000000, but guess that just comes from the compiler. I'm driving hobby servos - and they come out 4 times too long.
I guess my three questions are:-
Can anyone confirm the same experience?
Could they just be presetting the wrong clock pre scaler on start up? So all I need to do is write the correct pre scaler & all features will recover.
Have I given enough informatiion? Are they really 4Mz clocks?
For your information I bought this batch because they provide a USB C connector. I like not having to figure out connector orientation.
/*
* This code returns the Crystal Frequency divided by 1000.
* ( By Nick Gammon through Arduino Forum )
*/
#include <avr/sleep.h>
#include <avr/wdt.h>
volatile bool wdtFired;
// watchdog interrupt
ISR (WDT_vect)
{
wdt_disable(); // disable watchdog
wdtFired = true;
} // end of WDT_vect
void setup ()
{
noInterrupts (); // timed sequence follows
MCUSR = 0;
WDTCSR = bit (WDCE) | bit (WDE); // allow changes, disable reset, and set interrupt mode and an interval
WDTCSR = bit (WDIE); // set WDIE, and 16 ms seconds delay
wdt_reset(); // pat the dog
wdtFired = false;
interrupts ();
unsigned long startTime = micros ();
while (!wdtFired)
{ } // wait for watchdog
unsigned long endTime = micros ();
Serial.begin (9600);
Serial.println ();
Serial.print (F("Time taken = "));
Serial.println (endTime - startTime);
}
void loop () { }
You might try setting the clock prescaler back to 1
Place the code in setup()
cli(); // This next section of code is timing critical, so interrupts are disabled
// Start the timed Sequence for configuring the clock prescaller
CLKPR = 0x80;
CLKPR = 0x00;
sei(); // Enable interrupts
Great suggestion. I'm new to fiddling around this area so you have saved me time. I am in the middle of matters arising from JML Jackson, so I'll deal with that first, but I think you've given me just what I need to know I'm working with a 1 times prescalar. I'll get back to this.
Many thanks for your prompt input. I tried that on one of the problematic nanos & got nothing. Also tried on old stock nanos, which reported 16MHz (16,900, I think). So I modified your suggested code to include an initial intro message.
/*
* This code returns the Crystal Frequency divided by 1000.
* ( By Nick Gammon through Arduino Forum )
*/
#include <avr/sleep.h>
#include <avr/wdt.h>
volatile bool wdtFired;
// watchdog interrupt
ISR (WDT_vect)
{
wdt_disable(); // disable watchdog
wdtFired = true;
} // end of WDT_vect
void setup ()
{
Serial.begin (9600);
Serial.println ();
Serial.println ("12345678901234567890 Arduino Oscillator Check. Starting Test.");
delay(250);
noInterrupts (); // timed sequence follows
MCUSR = 0;
WDTCSR = bit (WDCE) | bit (WDE); // allow changes, disable reset, and set interrupt mode and an interval
WDTCSR = bit (WDIE); // set WDIE, and 16 ms seconds delay
wdt_reset(); // pat the dog
wdtFired = false;
interrupts ();
unsigned long startTime = micros ();
while (!wdtFired)
{ } // wait for watchdog
unsigned long endTime = micros ();
Serial.println ();
Serial.print (F("Time taken = "));
Serial.println (endTime - startTime);
}
void loop () { }
Old stock nano needs 9600 serial monitor & waits 1/4 second before reporting 16MHx. New stock needs 2400 monitor & waits 1 second before moving on.
Since I know each character is taking ~4msec, I deduce the watchdog timer is kicking in after, say, 64msec, not 16msec, but behaviour is different. My guess is watchdog mature is causing the processor to restart, and not execute the watchdog interrupt servicing routine.
const int nOnBoardLED = 13;
int nCycleCount;
void setup()
{
cli(); // This next section of code is timing critical, so interrupts are disabled
// Start the timed Sequence for configuring the clock prescaller
CLKPR = 0x80;
CLKPR = 0x00;
sei(); // Enable interrupts
Serial.begin(9600);
pinMode(nOnBoardLED, OUTPUT);
nCycleCount = 0;
}
void loop()
{
Serial.print("Nano Oscillator Test ");
Serial.println(++nCycleCount);
delay(2000);
digitalWrite(nOnBoardLED, !(digitalRead(nOnBoardLED)));
}
The Arduino code says run the serial out at 9600. I need to set IDE serial monitor to 19200 for sync! I set the delay to 2000 for a 1 second repeat period.
Running the same code on old stock nanos need 9600 serial monitor & has 2 second repeat period as you would expect.
I think you're saying my nano hasn't got an Atmega 328P processor. I'm guessing you think lgt8f382p tells me what you think it is. New to me, but I guess there's a crucial difference between something that says 382 and something that says 328. Never mind the other bits and pieces. I am rapidly coming to the conclusion that I've got a batch of orphans. Quckest & cheapest way forward is to scrap them & move on.
That was a caveat, of course lgt8f328p (WAVGAT)
It has a number of great features, so it's not worth getting rid of, here's a whole section on discussing this controller
@jim-p - thank you so much. With that, code says 9600 & delay() is accurate for new stock, but same code in old stock needs 4800 & delay increments every 2msec. @ua6em has suggested my new stock does not have an Atmel 328p.
My gut tells me to cut my losses and ditch the orphans. I'm afraid I can't read anything on the main processor chip.
Incidentally, @jim-p, from what you have told me these little widgets have a 32MHz clock and the pre-scalar is dividing that by 2 to make the cpu think it's 16. Actually, their setup does a divide by 8, making it think it's 4MHz, but your first suggested change had it successfully ticking away at 32MHz until I dropped that back to 16MHz for compatability with a standard nano - sort of!
@jim-p I think you offer sage advice, so I'll do that. I said earlier that I'm driving a collection of hobby servos using the servo library. I managed to drive that over the full range (180 degrees), but could only resolve to 3 degree steps. Using 16MHz clock I can get that back to 3/4 degree. I've still got to join up a bunch of TWI widgets. Here's hoping that will run smoothly. Once again. Thanks for your help.