4 MHz clock - USB C connector

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:-


const int nOnBoardLED = 13;

void setup() 
{
    Serial.begin(19200);
    pinMode(nOnBoardLED, OUTPUT);
}

void loop() 
{
    Serial.print(" F_CPU ");
    Serial.println(F_CPU);
    delay(1000);
    digitalWrite(nOnBoardLED, !(digitalRead(nOnBoardLED)));
}

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:-

  1. Can anyone confirm the same experience?
  2. 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.
  3. 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.

Yes, that does not mean anything about the real frequency.

It seems they got the wrong SMD quartz crystal on your batch.

can you try this code (By @nickgammon ):

/*
 * 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 ()  { }

what does it print?

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.

12345678901234567890 Arduino Oscillator Check. Starting Test.
12345678901234
1234567890123
1234567890123
1234567890123
1234567890123
1234567890123
1234567890123

Curiouser and curiouser, as Alice said to the white rabbit.

mmm ... @jim-p. Not the result I expected

Here's the revised code:-

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.

The problem is that not a real nano compatible board on lgt8f328p

Try changing the CLKPR = 0x00; to CLKPR=0x01;

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

Don't throw them out, they are indeed lgt8f328p running at 32MHz
Better than aplain old 328

if you set CLKPR=0x01; they will run at 16MHz

@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!

If you run them at 16MHz they will run any old 328 code you have.
Where did you buy them?

@jim-p Alibaba

I'd keep them and use them

Thanks to @ua6em

By the way, this controller has 4 timers

@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.

Just rummaging around I found a useful link relating to the lgt8f328p

lgt8f328p Arduino Clone

I've found an English language data sheet, but it's a translation from Chinese & not very digestable.