using millis() getting strange results

A little history:
I’ve been trying to remotely control a power supply output with a 0 to 5 volt signal. I tried using analogWrite(pin, xxx) with an RC filter but it doesn’t work quite right.
So I thought why not use a MUX (74HC4067). I simply configure a couple of dividers for the channel inputs. Then switch channel select S0 (chan 0 and chan 1) on and off at the desired rate. Specifically, a I second prf switching channel S0 off for 990 msec, transferring a .5 vdc via chan 0, then on for 10 msec, transferring 1.5vdc via chan 1. Brilliant! Right?
The delayMicroseconds() function works great. But I want to use a millis(), as part of a time synchronized acquisition application involving rms measurements and array calculations (but I digress).
Here’s the problem. The millis() function wont control the digital port properly. It produces some strange square wave, with the correct dc levels, but with irregular timing of the hi and low states of the digital port.
Can anyone verify this phenomenon? Perhaps my Arduino UNO is malfunctioning? Or why this is happening?

  unsigned long currentTimer1 = 0;
  unsigned long previousTimer1 = 0;
  unsigned long currentTimer2 = 0;
  unsigned long previousTimer2 = 0;

void setup() {
Serial.begin (9600);
  pinMode (4, OUTPUT); // enable
  digitalWrite (4,LOW);
  pinMode (5, OUTPUT); //channel select
  currentTimer1=millis();
  digitalWrite (5,LOW);
}

 void loop() { 

     if (currentTimer1 - previousTimer1 >=990){
       digitalWrite (5,1);
       previousTimer1 = currentTimer1;
       currentTimer2=millis();}
        
    if (currentTimer2 - previousTimer2 >= 1000){
       digitalWrite (5,0);
       previousTimer2 = currentTimer2;
       previousTimer1 = currentTimer1;}
      
 }
void setup() {
Serial.begin (9600);
  pinMode (4, OUTPUT); // enable
  //digitalWrite (4,LOW);
  pinMode (7, OUTPUT); //channel select
  digitalWrite (4,0);

}

 void loop() { 

 digitalWrite (7,HIGH);
 delayMicroseconds (10000);
 digitalWrite (7,LOW);
 delay(990);
 
  //this has to loop here or it won't work
 }

millis returns _milli_seconds.

delayMicroseconds delays _micro_seconds.

In Ver1 you delay 10000 and 990 microseconds.

In Ver2 you delay 10 and 990 milliseconds (10000 and 990000 microseconds).

Scratch that.

if (currentTimer1 - previousTimer1 >=990);{
if (currentTimer2 - previousTimer2 >= 10);{

Lose the ;.

So, to start off...you write to us as if everybody knows exactly what your talking about, for example, what is a prf, what is an rms, what is RC filter?

Next problem, post your code in code tags, dont make them attachments, people dont want to download attachments...

Anyway, I looked at your code and found the problem in about 2.6 seconds of looking at it...

if (currentTimer1 - previousTimer1 >=990);{

Da hell is that semi-colon doing there?!?!

Your if statements should not have a semicolon before the curly bracket.
Otherwise you terminate the if statement at the semicolon.

Ps991:
So, to start off...you write to us as if everybody knows exactly what your talking about, for example, what is a prf, what is an rms, what is RC filter?

Next problem, post your code in code tags, dont make them attachments, people dont want to download attachments...

Anyway, I looked at your code and found the problem in about 2.6 seconds of looking at it...

if (currentTimer1 - previousTimer1 >=990);{

Da hell is that semi-colon doing there?!?!

Please use a civil language.

Thanks for the input
I modified the post to use tabs and noted that the ide did compile even with the semicolon.
the milli() function still interferes with the timing... I don't think it is the numbers though.

so, show us the code

geneleduc:
Thanks for the input
I modified the post to use tabs and noted that the ide did compile even with the semicolon.
the milli() function still interferes with the timing... I don't think it is the numbers though.

It will compile with the semicolon there. It's not illegal code. It just makes the if statement useless and runs that block of code unconditionally. Which can give you some pretty erratic results.

try this

    if (millis() - previousTimer1 >= 990){
       digitalWrite (5,1);
       previousTimer1 = millis();
    }
        
    if (millis() - previousTimer2 >= 1000){
       digitalWrite (5,0);
       previousTimer1 = millis();
       previousTimer2 = millis();
    }

ignore what is below for now!

Okay...well then lets get more technical
Please try this and tell us if it works.

void setup() {
  
  int frequency = 1000; //1000 hz, every 1 milliseconds
  //Interupt Service Routine and timer setup
  noInterrupts();// kill interrupts until everybody is set up
  //We use Timer 1 to refresh, its the only 16 bit timer
  TCCR1A = B00000000;//Register A all 0's since we're not toggling any pins
    // TCCR1B clock prescalers
    // 0 0 1 clkI/O /1 (No prescaling)
    // 0 1 0 clkI/O /8 (From prescaler)
    // 0 1 1 clkI/O /64 (From prescaler)
    // 1 0 0 clkI/O /256 (From prescaler)
    // 1 0 1 clkI/O /1024 (From prescaler)
  TCCR1B = B00001011;//bit 3 set for CTC mode, will call interrupt on counter match, bits 0 and 1 set to divide clock by 64, so 16MHz/64=250kHz
  TIMSK1 = B00000010;//bit 1 set to call the interrupt on an OCR1A match
  OCR1A  = (unsigned long)(250000UL / frequency) - 1UL);//our clock runs at 250kHz, which is 1/250kHz = 4us

  interrupts();//let the show begin, this lets the multiplexing start

  pinMode(7, OUTPUT);
  digitalWrite(7, LOW);
}

void loop() {

}

volatile int interruptCount = 0;
ISR(TIMER1_COMPA_vect){ //Interrupt Service Routine, Timer/Counter1 Compare Match A
  if(interruptCount == 990 - 1)
    PORTD |= _BV (7); // digitalWrite (7, HIGH);
  else if(interruptCount == 1000 - 1)
    PORTD &= ~_BV (7); // digitalWrite (7, LOW);
  
  interruptCount = (interruptCount + 1) % 1000;
}

geneleduc:

  unsigned long currentTimer1 = 0;

unsigned long previousTimer1 = 0;
  unsigned long currentTimer2 = 0;
  unsigned long previousTimer2 = 0;

void setup() {
Serial.begin (9600);
  pinMode (4, OUTPUT); // enable
  digitalWrite (4,LOW);
  pinMode (5, OUTPUT); //channel select
  currentTimer1=millis();
  digitalWrite (5,LOW);
}

void loop() {

if (currentTimer1 - previousTimer1 >=990){
      digitalWrite (5,1);
      previousTimer1 = currentTimer1;
      currentTimer2=millis();}
       
    if (currentTimer2 - previousTimer2 >= 1000){
      digitalWrite (5,0);
      previousTimer2 = currentTimer2;
      previousTimer1 = currentTimer1;}
     
}

First off, there is only one current time. So you only need one currentTimer variable.

Secondly, you need to update that variable at the start of loop. In the code you have here, you are only updating currentTimer2 and you only do it in that if block when the other timer goes off. Nowhere in that loop do you update the value of currentTimer1.

The demo several things at a time is an extended example of using millis() for timing.

...R

Thanks everyone for your time and effort, this is a great place to learn!

/*
ct and et are current timmer and elapsed timmer


*/
unsigned long ct1;
unsigned long et1 = 0;
unsigned long et2 = 0;

void setup() {
  Serial.begin (9600);
  pinMode (4, OUTPUT); // enable
  pinMode (5, OUTPUT); //channel select
  digitalWrite (4, 0); for your time and tallents
  }

void loop() {

  if (millis() - et1 >= 1000) {
    digitalWrite (5, HIGH);
    et1 = millis();
  }

  if ( millis()- et2 >= 1010) {
    digitalWrite (5, LOW);
    et2 = millis();
    et1= millis();
  }
}

Gene L