Capacitor Voltage Point Counter

Hey thanks for viewing my post, im having issues with how to get the voltage value of a capacitor by this i mean. When im i use the serial monitor the voltage value has a difference of about 30 ms between the current and the next reading and this conflicts with my period of 0ms and 2 ms of the the wave.I would like it so that if i start at a measurement at zero seconds the next voltage capture would be at .00001s and proceed to capture the voltage in these increments untill i reach 2ms.The code in the loop is what i copied from this forum to try and grab 100 samples in 1ms but i cant seem to grab those value. the waveform and the outputs from the command line are posted on the bottom.


#include <PWM.h>//library to adjust pwm frequency
float val;  
long lastMillis = 0;
long loops = 0;
int32_t frequency =1000;//set the frequency
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); // open the serial port at 9600 bps:
  
InitTimersSafe();
SetPinFrequencySafe(3,frequency);//tells arduino that this pwm will have frency = f


}

void loop() {
//copied from forum//
long currentMillis = millis();
loops++;
if(currentMillis - lastMillis <= 1){
Serial.print("Loops last second:");
Serial.println(loops);
lastMillis = currentMillis;
loops = 0;
  for ( int i=0; i <100; i++)
  {
//my code    
pwmWrite(3,127); // sets pin 3 as output and at 50% duty cycle bc 127/255 is about .5 

val= analogRead(A5)*(5.0/1023.0);//normlize voltage from analog write

Serial.println(val);
//
  }}}

the point of this code is to find the time where Vc= 0.7 V using Vc(t)= Vs(1-e^(-t/RC)) t>0

i’ve often used what i’ve called a trace buffer to capture real-time events without interfering with real-time performance. The events are captured in real-time and the buffer displayed afterwards

so create an array and capture your 100 (?) points of data without any Serial prints. I’ve used the following program to exercise specific routines at run time.

create a capture function and a display function. Commands can be added to pcRead to invoke them at run-time. commands can be added to change parameters, re-capture, re-report. Saves you the trouble of rebuilding the code and running it just once

// pcRead - debugging using serial monitor

const char version [] = "PcRead 200416a";

int debug = 0;

// ---------------------------------------------------------
// toggle output bit
void
pinToggle (
    int pin)
{
    static int  bits = 0;
    int     bit = 1 << pin;

    if (debug)  {
        Serial.print ("pinToggle: ");
        Serial.println (pin);
    }

    if (bits & bit)  {
        digitalWrite (pin, LOW);
        bits &= ~bit;
    }
    else {
        digitalWrite (pin, HIGH);
        bits |= bit;
    }
}

// ---------------------------------------------------------
// toggle output bit
int
readString (
    char *s,
    int   maxChar )
{
    int  n = 0;

    Serial.print ("> ");
    do {
        if (Serial.available()) {
            int c    = Serial.read ();

            if ('\n' == c)
                break;

            s [n++] = c;
            if (maxChar == n)
                break;
        }
    } while (true);

    return n;
}

// -----------------------------------------------------------------------------
// process single character commands from the PC
#define MAX_CHAR  10
char s [MAX_CHAR] = {};

void
pcRead (void)
{
    static int  analogPin = 0;
    static int  val = 13;

    if (Serial.available()) {
        int c = Serial.read ();

        switch (c)  {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            val = c - '0' + (10 * val);
            break;

        case 'A':
            analogPin = val;
            Serial.print   ("analogPin = ");
            Serial.println (val);
            val = 0;
            break;

        case 'D':
            debug ^= 1;
            break;

        case 'I':
            pinMode (val, INPUT);
            Serial.print   ("pinMode ");
            Serial.print   (val);
            Serial.println (" INPUT");
            val = 0;
            break;

        case 'O':
            pinMode (val, OUTPUT);
            Serial.print   ("pinMode ");
            Serial.print   (val);
            Serial.println (" OUTPUT");
            val = 0;
            break;

        case 'P':
            pinMode (val, INPUT_PULLUP);
            Serial.print   ("pinMode ");
            Serial.print   (val);
            Serial.println (" INPUT_PULLUP");
            val = 0;
            break;


        case 'a':
            Serial.print   ("analogRead: ");
            Serial.println (analogRead (val));
            val = 0;
            break;

        case 'c':
            digitalWrite (val, LOW);
            Serial.print   ("digitalWrite: LOW  ");
            Serial.println (val);
            val = 0;
            break;

        case 'p':
            analogWrite (analogPin, val);
            Serial.print   ("analogWrite: pin ");
            Serial.print   (analogPin);
            Serial.print   (", ");
            Serial.println (val);
            val = 0;
            break;

        case 'r':
            Serial.print   ("digitalRead: pin ");
            Serial.print   (val);
            Serial.print   (", ");
            Serial.println (digitalRead (val));
            val = 0;
            break;

        case 's':
            digitalWrite (val, HIGH);
            Serial.print   ("digitalWrite: HIGH ");
            Serial.println (val);
            val = 0;
            break;

        case 't':
            Serial.print   ("pinToggle ");
            Serial.println (val);
            pinToggle (val);
            val = 0;
            break;

        case 'v':
            Serial.print ("\nversion: ");
            Serial.println (version);
            break;

        case '\n':          // ignore
            break;

        case '"':
            while ('\n' != Serial.read ())     // discard linefeed
                ;

            readString (s, MAX_CHAR-1);
            Serial.println (s);
            break;

        case '?':
            Serial.println ("\npcRead:\n");
            Serial.println ("    [0-9] append to #");
            Serial.println ("    A # - set analog pin #");
            Serial.println ("    D # - set debug to #");
            Serial.println ("    I # - set pin # to INPUT");
            Serial.println ("    O # - set pin # to OUTPUT");
            Serial.println ("    P # - set pin # to INPUT_PULLUP");
            Serial.println ("    a # - analogRead (pin #)");
            Serial.println ("    c # - digitalWrite (pin #, LOW)");
            Serial.println ("    p # -- analogWrite (analogPin, #)");
            Serial.println ("    r # - digitalRead (pin #)");
            Serial.println ("    s   - digitalWrite (pin #, HIGH)");
            Serial.println ("    t   -- toggle pin # output");
            Serial.println ("    v   - print version");
            Serial.println ("    \"   - read string");
            Serial.println ("    ?   - list of commands");
            break;

        default:
            Serial.print ("unknown char ");
            Serial.println (c,HEX);
            break;
        }
    }
}

// -----------------------------------------------------------------------------
void
loop (void)
{
    pcRead ();
}

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

    Serial.println (version);
}

Hey, gcjr so basically i should just make an array of size sample, loop through it loop -1 times and assign the value of voltage to the array at index i as analogRead(Input_Pin).

i also lookd more into the behavior of the analogRead function and it says it takes about 100 microseconds or (0.1ms) to read a measurement so each analog read in the array would be read .1ms at a time?

i also ran a test on it and the average run time according to the time stamp on the serial monitor is 34-35 ms. This is after collecting the value from analog read then passing it to a different for loop to read it out and put a timestamp from the ide to see how many milliseconds it took between each print.

i was expecting that in each index i would have 0.1 at index zero, .2 at index 1....
im going to make a 200 element sized array with every even holding the time (using millis()) and every odd holding the voltage value.

i would capture time in a second array.

but i'm surprised you need to sample as quickly as that

Hey greg, i figured that the slope for of the Vc(t) is too steep for the arduino to collect data from. I confrimed this by decreasing the slope with decreasing the period from 1ms to about 1 second i wanted tou to last about the time it took for half the period so .5ms in the previous example and .5 seconds in this one . but the .5 second did not work because the min frequency for the pwm is about 40Hz using the <PWM.h> header.

so I set 5*tou= 1/40 s

tou = .005s and picked a capacitor with 10uF making R = 500 ohms and got a less steeper plot and when i started collecting data it seemed consistent. So i made the slope less steeper by replacing the capacitor. Any how this is a step project for measuring IC of a bjt for variying VBE and VCE.

my final code with time millis() is this.


#include <PWM.h>//library to adjust pwm frequency
unsigned long time;
int32_t frequency =40;//set the frequency

double array[200];
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600); // open the serial port at 9600 bps:  
InitTimersSafe();
SetPinFrequencySafe(3,frequency);//tells arduino that this pwm will have frency = f
pwmWrite(3,127); // sets pin 3 as output and at 50% duty cycle bc 127/255 is about .5 
for(int i=0;i<1;i++){
for(int j=0;j<100;j++){
time = millis();
array[i *100 + 2*j]=analogRead(A5)*(5.0/1023.0);//normlize voltage from analog write

array[1+i *100 + 2*j]=(time);//set every odd value in the array to time
}
}
for(int i =0;i<1;i++){
for(int j =0;j<100;j++){

Serial.println((String)"Voltage is: "+array[2*j+i*100]+", Time is: "+array[2*j+i*100+1]);
}}

}
void loop() {

}

In the future i am going to use the arduino zero because in the analog read page it says that i can adjust the precission.