Go Down

Topic: Real Time Monitoring Of Software Variable (Read 92 times) previous topic - next topic

harveyn

If there is code running on an Arduino Uno R3 board, is there a way to monitor the real time calculated value of a variable within the software?

groundFungus

Can't you, periodically, print the value over Serial to serial monitor?

If you want better help, post the code and tell us what you want to do.  More detail means faster and better help.

Read the how to use this forum sticky to see how to post code and some advice on how to get the most from the forum.

harveyn

In the below code I would like to monitor the value of Vcap real-time.
What would be the best way to monitor the value of this variable?


[code
Code: [Select]

// Pin definitions
const int PWM = 9;
const int SCLK = 3;
const int DISC = 4;
const int LED = 5;
const int VADC = A0;

unsigned int ton_clocks = 24;
unsigned int toff_clocks = 4000;
unsigned int loopCount = 0;

// Initialization
void setup()
{
  // Initialize I/O pins
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

  pinMode(PWM, OUTPUT);
  digitalWrite(PWM, LOW);

  pinMode(SCLK, OUTPUT);
  digitalWrite(SCLK, HIGH);

  pinMode(DISC, OUTPUT);
  digitalWrite(DISC, LOW);
 
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);

  // Disable interrupts during timer setup
  noInterrupts();

  // Initialize timer1 (PWM)
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  TCCR1A |= (1 << COM1A1);  // Clear OC1A on compare match, set at BOTTOM
  TCCR1A |= (1 << WGM11);   // Fast PWM mode, TOP = ICR1
  TCCR1B |= (1 << WGM12) | (1 << WGM13);
  OCR1A = ton_clocks;               // PWM on-time (in clocks)
  ICR1 = toff_clocks + ton_clocks;  // PWM period (in clocks)
  TIMSK1 |= (1 << TOIE1);   // Enable overflow interrupt
  TCCR1B |= (1 << CS10);    // Start timer, no prescaling

  // Enable interrupts
  interrupts();
}

// Timer1 overflow ISR
ISR(TIMER1_OVF_vect)
{
  // Update the PWM period
  ICR1 = toff_clocks + ton_clocks;  // PWM period (in clocks)
}

// Main loop
void loop()
{
  // Drive SCLK low for at least 5 ms (activate sampling circuit)
  digitalWrite(SCLK, LOW);
  delay(1);

  // Sample the ADC voltage
  float VADC_voltage = analogRead(VADC) * (5.f / 1023.f);
  float Vcap = -213.48f*VADC_voltage;
  // Enforce the upper bound for toff by checking the cap voltage directly
  // This avoids a potential divide-by-zero condition
  if (abs(Vcap) < 1.43)
    toff_clocks = 250*16;
  else
    toff_clocks = (unsigned int)(16.f * (297.f / abs(Vcap)));
  // Also enforce a lower bound for off time (just to be safe).Val of 11 clkcycs=0.69us min off-time
  if (toff_clocks < 10)
    toff_clocks = 10;

  // Check if we've reached the target voltage or not (-400VDC)
  if (Vcap < -400.f)
  {
    // If so, disable the PWM output
    digitalWrite(PWM, LOW);
    TCCR1A &= ~(1 << COM1A1);
    digitalWrite(LED, HIGH);
  }
  else // Otherwise enable the PWM output
  {
    TCCR1A |= (1 << COM1A1);
    digitalWrite(LED, LOW);
  }

  // Drive SCLK high (done sampling)
  digitalWrite(SCLK, HIGH);

  // Wait to sample again
  delay(1000);

  // Discharge the capacitors every so often
  /*loopCount++;
  if (loopCount >= 150)
  {
    loopCount = 0;

    // Reset toff to ensure we don't saturate the transformer primary
    toff_clocks = 250*16;
    digitalWrite(DISC, HIGH);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(5000);
    digitalWrite(DISC, LOW);
    digitalWrite(LED_BUILTIN, LOW);
  }*/
}
][/code]

pert

In the setup() function, add this:
Code: [Select]
Serial.begin(9600);
Wherever you want to output the value of Vcap, add this line:
Code: [Select]
Serial.println(Vcap);
Now upload your sketch and then click Tools > Serial Monitor. You will see the value of Vcap printed to the Serial Monitor. You can add additional Serial.println() statements to get other output from your code if needed.

This is the most common form of debug output used in the Arduino world. It's easy, but it does have its issues. Serial communication is fairly slow, so these debug prints can cause problems for timing-sensitive code. I recommend against using Serial in the ISR function.

For timing sensitive situations when you only need to convey some simple debug information, toggling an LED connected to a spare pin can be effective, and with much less overhead.

You might also find that serial debug output can push your code past the available memory on the microcontroller when your sketch is already using a lot without the debug code. A possible solution to that is to use a microcontroller with more memory (e.g. Arduino Mega) during development, then switch back to the smaller microcontroller once the project is finished.

A more professional solution would be to use a hardware debugger. This is supported by the ATmega328P microcontroller of your Uno, but there is no integration for hardware debugging in the Arduino IDE, so there is a pretty steep learning curve involved with moving beyond serial debug output.

Go Up