Doesn't work without USB (apparently it changes the frequency of the timer)

Hi.

When I open the terminal on Arduino, the programm works fine. But when I don’t connect the USB nothing works.

In my programm, I use the Timer1 because the Timer0 is used for PWM output. I have a periodic routine that allows to run some code. I have discovered that if I change the frequency of this routine to the half, the program does work fine.

I cann’t explain this behaviur. Is like if using the serial port changed the time that the code requieres to run. Can somebody help me?

Thanks.

Can somebody help me?

Without seeing your code? No.

PaulS: Without seeing your code? No.

The code is too long. What part of the code could be interesting? The ISR routine, the setup loop? Because of that I wanted to know what can do this, for post the code where it appears.

The code is too long.

You have more than a megabyte of code? For which Arduino?

Use Reply and the Additional Options link to attach your code.

Ok, I have reduce the code a lot: I am going to post that I consider the most important:

The main:

#define I2C_SPEED 800000L   //800kHz ultra fast 

// MOTOR
#define MOTORUPDATE_FREQ 200
#define CC_FACTOR 32


float deltat = 0.0f;        // integration interval for both filter schemes
bool motorUpdate = false;
int freqCounter = 0;

uint32_t lastUpdate = 0; // used to calculate integration i
uint32_t Now = 0;        // used to calculate integration interval

void setup()
{
  Serial.begin(115200);

  Wire.begin();
  TWSR = 0;                                  // no prescaler => prescaler = 1
  TWBR = ((16000000L / I2C_SPEED) - 16) / 2; // change the I2C clock rate
  TWCR = 1 << TWEN;                          // enable twi module, no interrupt

  LEDPIN_ON
  Serial.println("Ready");
}

void loop()
{
  float Now;

  if (motorUpdate)
  {
    motorUpdate = false;

    readACCs();
    readGyros();

    Now = microsT1();
    deltat = ((Now - lastUpdate) / 1000000.0f); // set integration time by time elapsed since last filter update
    lastUpdate = Now;

    updateGyro();  //1100 us

    getAngles(); //55us

  }
}

/********************************/
/* Motor Control IRQ Routine    */
/********************************/
ISR( TIMER1_OVF_vect )
{
  freqCounter++;
  if (freqCounter == (CC_FACTOR * 1000 / MOTORUPDATE_FREQ))
  {
    freqCounter = 0;
    // update event
    motorUpdate = true;
  }


  // care for standard timers every 1 ms
  if ((freqCounter & 0x01f) == 0) {
    TIMER0_isr_emulation();
  }

}

and the Timer1 functions are:

// the prescaler is set so that timer0 ticks every 64 clock cycles, and the
// the overflow handler is called every 256 ticks.
#define MICROSECONDS_PER_TIMER1_OVERFLOW (clockCyclesToMicroseconds(64 * 256))

// the whole number of milliseconds per timer0 overflow
#define MILLIS_INC_T1 (MICROSECONDS_PER_TIMER1_OVERFLOW / 1000)

volatile unsigned long timer1_millis;

/***************************************************************************/
/* Timer0 interrupt emulation
/***************************************************************************/
void TIMER0_isr_emulation (void) {

  unsigned long m = timer1_millis;

  m += MILLIS_INC_T1;
  timer1_millis = m;

}


unsigned long millisT1() {
  unsigned long m;
  uint8_t oldSREG = SREG;
  // disable interrupts while we read timer1_millis or we might get an
  // inconsistent value (e.g. in the middle of a write to timer1_millis)
  cli();
  m = timer1_millis;
  SREG = oldSREG;
  return m;
}

unsigned long microsT1() {

  unsigned long m;

  uint8_t oldSREG = SREG;
  uint8_t f;

  cli();
  m = timer1_millis;
  f = (freqCounter & 0x01f) << 3;
  SREG = oldSREG;

  return ((m << 8) + f) * (64 / clockCyclesPerMicrosecond());
}

void delayT1(unsigned long ms)
{
  uint16_t start = (uint16_t)millisT1();
  while (ms > 0) {
    if (((uint16_t)millisT1() - start) >= 1) {
      ms--;
      start += 1;
    }
  }
}

There are functions that I am not put in here, but works well and it only reads from sensors…

That seems to be a very complex program. You need to provide an explanation of how each of the different parts work and interact with each other.

If I were to create a .ino file with the code in your Reply #4 would it compile and work to demonstrate your problem?

...R

If you want the problem found, we need to recreate the same problem - so you have to post code that compiles, downloads, runs and exhibits the problem, plus an explanation of what the problem is (the expected behaviour v. the actual behaviour). If you can produce a smaller example of a sketch with the same issue, that's useful, because you may figure it out during the process. Sometimes the sketch requires particular hardware - that is going to reduce the chance of recreating the problem, but there's still a chance of spotting it by eye.

I'll take a swag (Scientific Wild A$$ed Guess) at it. Sounds like a noise issue. When you cut the rate in half, you increase noise rejection.

Consider this: When you are attached to USB, your Arduino ground is tied to the PC's ground and it probably has a DC path to earth which helps with noise rejection (in most cases). When you run untethered, your Arduino is ungrounded unless there is a path by way of a sensor.

I had a water pressure measurement system that worked while on USB but when running on battery, the sensor noise was so bad the signal was unusable. The culprit was stray 60hz mains noise being picked up by the high impedance sensor and no amount of filtering would help. In the end, a 0.1uf 500v film cap from common of the Arduino to earth (a nearby copper cold water pipe) solved the problem.

MarkT: If you want the problem found, we need to recreate the same problem - so you have to post code that compiles, downloads, runs and exhibits the problem, plus an explanation of what the problem is (the expected behaviour v. the actual behaviour). If you can produce a smaller example of a sketch with the same issue, that's useful, because you may figure it out during the process. Sometimes the sketch requires particular hardware - that is going to reduce the chance of recreating the problem, but there's still a chance of spotting it by eye.

I know that, but is impossible to you to use my code, because you will need brushless motors, IMU, etc. Because of that, I am going to explain what does the program, just in case anyone can help me.

I use 6 output as PWM at 32Khz for motors. The output will updated each t seconds, where I choose t. This is my ISR routine. At the main program, I read IMU, calculate the output for the motors, etc . I have configurate the Timer1 for the ISR routine, because Timer0 is useless because the PWM outputs.

When I connect the USB and OPEN the terminal (both), my program works perfect at 200 Hz (5 microseconds). The motors has is own battery.

The problem comes when only connect the USB and do not open the terminal, then the programm don't works. Same if I connect a power supply instead the USB. I tried a lot of things, and looks that when I put the frequency at 100 Hz, the program works (but not fine, because all is calculated to works at 200 Hz). It's like when I do not open the terminal frequency varies.

If with this explanation anyone can help me I will be happy, if not don't worry, I know that is difficult without see the program.

Thanks.

avr_fred: I had a water pressure measurement system that worked while on USB but when running on battery, the sensor noise was so bad the signal was unusable. The culprit was stray 60hz mains noise being picked up by the high impedance sensor and no amount of filtering would help. In the end, a 0.1uf 500v film cap from common of the Arduino to earth (a nearby copper cold water pipe) solved the problem.

An interesting observation - worth filing away for future reference

But does not sound as if it is relevant to the OP's problem.

...R

Joaqks: I use 6 output as PWM at 32Khz for motors. The output will updated each t seconds, where I choose t. This is my ISR routine. At the main program, I read IMU, calculate the output for the motors, etc . I have configurate the Timer1 for the ISR routine, because Timer0 is useless because the PWM outputs.

What Arduino are you using?

Timer0 is normally used for millis() and micros(). Are you upsetting it by using it for PWM at 32Khz? Is it possible that using the Serial port sets Timer0 back to its "normal" settings?

...R

Robin2: What Arduino are you using?

Timer0 is normally used for millis() and micros(). Are you upsetting it by using it for PWM at 32Khz? Is it possible that using the Serial port sets Timer0 back to its "normal" settings?

...R

I am using Arduino pro mini. I use microsT1() and millisT1(), and works perfect if I open the terminal. To configure the PWM output, I change the registers of Timer 0, and because that I have to use Timer 1.

The thing is that it seems that if I open the terminal everything runs at a certain time, and if I do not open it all takes longer to run.

Is there any instruction that simulate to open the terminal? I could put it in the program and see whats happens....

I just fix that. I don't know what happens, and never will know. But I have put a delayT1(1000) at the end of the setup function, and all works fine without terminal and USB.

Thanks a lot.

Joaqks: I just fix that. I don't know what happens, and never will know. But I have put a delayT1(1000) at the end of the setup function, and all works fine without terminal and USB.

That's good to hear because I have absolutely no idea what you mean by microsT1(), millisT1() or delayT1().

...R

Robin2: That's good to hear because I have absolutely no idea what you mean by microsT1(), millisT1() or delayT1().

...R

Same functions than micros(), delay() and millis(), but using the Timer 1 instead the Timer 0.