Initial revision
[sensors.git] / src / Cmeter.cpp
1 #include <iostream>
2 #include <iomanip>
3 #include <fstream>
4
5 #include <stdio.h>
6 #include <unistd.h>
7 #include <pigpiod_if2.h>
8
9
10 #define CYCLE_OUT   18    // The cycle output
11 #define CMP_IN      17    // The signal from the comparator
12 #define NR_SAMPLES  20    //  Number of samples to avaerage out the jitter
13
14 void gpio_callback(int pi, unsigned user_gpio, unsigned level, uint32_t tick, void * userdata);
15
16 #define INPUT_OFFSET 0.97
17 #define INPUT_DIVIDER 0.086
18 #define SLOPE_FACTOR  38.7   //  Current / Voltage ( 117uA / 3.0V)
19
20 class DVM
21 {
22    int      pi;    // Connection to pigpio daemon
23    unsigned cycle_gate;  // The gate to run a measurement cycle
24    unsigned comparator;  // The signal from the comparator
25
26
27    uint32_t last_tick;
28    uint32_t measure_start;
29
30    uint32_t samples[NR_SAMPLES];
31    int      sample_index;
32
33    float U;  //  The measured voltage
34
35
36 public:
37
38    void input_event(unsigned gpio, unsigned level, uint32_t tick)
39    {
40       float measure_time;
41
42       //printf("Input event: input %u = %u, %d\n", gpio, level, tick - last_tick);
43
44       if (gpio == cycle_gate && level == 1)
45       {
46          measure_start = tick;
47       }
48
49       if (gpio == comparator && level == 1)
50       {
51          samples[sample_index++] = tick - measure_start;
52          sample_index %= NR_SAMPLES;
53
54          measure_time = (float)(tick - measure_start) / 1.0e6;
55          U = measure_time * 11.4 - INPUT_OFFSET;
56          U /= INPUT_DIVIDER;
57
58          gpio_write(pi, cycle_gate, 0);
59       }
60       if (gpio == comparator && level == 0)
61       {
62          gpio_write(pi, cycle_gate, 1);
63       }
64       last_tick = tick;
65    }
66
67    
68    DVM(int pi_connection, unsigned gate, unsigned cmp)
69    {
70       int open_return;
71
72       pi         = pi_connection;
73       cycle_gate = gate;
74       comparator = cmp;
75
76       last_tick = 0;
77       sample_index = 0;
78
79
80       set_mode(pi, comparator, PI_INPUT);
81       set_mode(pi, cycle_gate, PI_OUTPUT);
82       set_pull_up_down(pi, comparator, PI_PUD_OFF);
83
84       open_return = callback_ex(pi, cycle_gate, EITHER_EDGE, gpio_callback, this);
85       //fprintf(stderr, "Set callback returns %d.\n", open_return);
86       open_return = callback_ex(pi, comparator, EITHER_EDGE, gpio_callback, this);
87       //fprintf(stderr, "Set callback returns %d.\n", open_return);
88       gpio_write(pi, cycle_gate, 0);
89       sleep(1);
90       gpio_write(pi, cycle_gate, 1);
91    }
92
93    float Voltage()
94    {
95       uint32_t sum = 0;
96       uint32_t average_time;
97       float measure_time;
98
99       //  To filter out the jitter, calculate the average measured time
100
101       for (int i = 0; i < NR_SAMPLES; i++)
102       {
103          sum += samples[i];
104       }
105
106       average_time = (sum / NR_SAMPLES) >> 5 << 5;
107       std::cout << " Average time = " << average_time << "\n";
108       measure_time = average_time / 1.0e6;
109       U = measure_time * SLOPE_FACTOR;
110
111       return U;
112    }
113 };
114
115 void gpio_callback(int pi, unsigned user_gpio, unsigned level, uint32_t tick, void * userdata)
116 {
117    DVM *sensor;
118
119    sensor = (DVM *)userdata;
120    sensor->input_event(user_gpio, level, tick);
121 }
122
123
124 int main()
125 {
126    int pi;
127    std::ofstream sensorfile;
128
129    pi = pigpio_start(NULL, NULL);
130    if (pi < 0)
131    {
132               // pigpio initialisation failed.
133       fprintf(stderr, "GPIO initialization failed.\n");
134
135    }
136    else
137    {
138               // pigpio initialised okay.
139       DVM sensor(pi, CYCLE_OUT, CMP_IN);
140
141       while (true)
142       {
143          sleep(1);
144          printf("%.3f\n", sensor.Voltage());
145          fflush(stdout);
146
147          sensorfile.open("sensor1");
148          sensorfile << std::fixed << std::setprecision(3) << sensor.Voltage() << " uF\n";
149          sensorfile.close();
150       }
151       pigpio_stop(pi);
152
153    }
154
155 }
156