analogRead during the middle of a Pwm!

I'm having trouble controlling the current on a pwm motor controller. I am using timer 1 on pin 10 to generate a 15.6 Khz signal and a Lem current sensor. I am taking 8 readings every loop of the main loop and each time if it is above the set limit, it reduces the duty by 1. The problem is that the reading does not always land during a on spot of the pwm. Ive looked around and I just cant figure out how to take a reading during the on or high part of the pmw. I would like to only take readings when the pwm is high or on. Any Ideas?

I ran this test program with the output of the Fet shorted and a 12v supply.

int p = 0;
#define pwm 10         // PWM Pin
void setup()

{
  //  Sets Timer1 to Phase Correct
  //  F_CLOCK / ( Prescaler * ORCR1A * 2 ) = Freq in Hz
  //  16000000 / (1 * 512 * 2 ) = 15625 Hz
  TCCR1A = _BV (WGM10) | _BV (WGM11) | _BV (COM1B1);  // Phase Correct
  TCCR1B = _BV (WGM13) | _BV (CS12);                  // Phase Correct / Prescale 1
  OCR1A = 512;                                        // Sets Top to 512 
  OCR1B = 0;                                          // Sets Pwm = 0			

  // Setup Input / Output
  pinMode(pwm, OUTPUT);           
  pinMode(1, INPUT);

     Serial.begin(9600);
}

void loop()

{
  p++;
  OCR1B = p;
  Debug();
  while (p > 255) {
    OCR1B = 0;}
}

  void Debug()
    {
     Serial.print("p = "); Serial.print(p); Serial.print(" ");
     Serial.print("pin 1 = "); Serial.println(analogRead(1));
    }

This was the out put of the serial port for the current sensor with the duty from 0 to 50 percent. My volt meter read a steady clime from 0 to 0.32 volt on pin 1
I am unsure how to get a smooth reading with constant values. It should have read from 0 to 65. I looked at the output from the Lem current sensor and it of course looks like the output of the pwm.
p = 1 pin 1 = 0
p = 2 pin 1 = 0
p = 3 pin 1 = 0
p = 4 pin 1 = 0
p = 5 pin 1 = 0
p = 6 pin 1 = 0
p = 7 pin 1 = 0
p = 8 pin 1 = 0
p = 9 pin 1 = 0
p = 10 pin 1 = 0
p = 11 pin 1 = 0
p = 12 pin 1 = 0
p = 13 pin 1 = 0
p = 14 pin 1 = 0
p = 15 pin 1 = 0
p = 16 pin 1 = 0
p = 17 pin 1 = 0
p = 18 pin 1 = 0
p = 19 pin 1 = 0
p = 20 pin 1 = 0
p = 21 pin 1 = 0
p = 22 pin 1 = 0
p = 23 pin 1 = 0
p = 24 pin 1 = 0
p = 25 pin 1 = 0
p = 26 pin 1 = 0
p = 27 pin 1 = 0
p = 28 pin 1 = 0
p = 29 pin 1 = 0
p = 30 pin 1 = 0
p = 31 pin 1 = 0
p = 32 pin 1 = 0
p = 33 pin 1 = 0
p = 34 pin 1 = 0
p = 35 pin 1 = 0
p = 36 pin 1 = 0
p = 37 pin 1 = 0
p = 38 pin 1 = 0
p = 39 pin 1 = 0
p = 40 pin 1 = 0
p = 41 pin 1 = 0
p = 42 pin 1 = 0
p = 43 pin 1 = 0
p = 44 pin 1 = 0
p = 45 pin 1 = 0
p = 46 pin 1 = 0
p = 47 pin 1 = 0
p = 48 pin 1 = 0
p = 49 pin 1 = 0
p = 50 pin 1 = 0
p = 51 pin 1 = 0
p = 52 pin 1 = 0
p = 53 pin 1 = 0
p = 54 pin 1 = 0
p = 55 pin 1 = 0
p = 56 pin 1 = 0
p = 57 pin 1 = 0
p = 58 pin 1 = 0
p = 59 pin 1 = 0
p = 60 pin 1 = 0
p = 61 pin 1 = 0
p = 62 pin 1 = 122
p = 63 pin 1 = 0
p = 64 pin 1 = 0
p = 65 pin 1 = 0
p = 66 pin 1 = 0
p = 67 pin 1 = 0
p = 68 pin 1 = 120
p = 69 pin 1 = 0
p = 70 pin 1 = 0
p = 71 pin 1 = 0
p = 72 pin 1 = 0
p = 73 pin 1 = 0
p = 74 pin 1 = 0
p = 75 pin 1 = 129
p = 76 pin 1 = 0
p = 77 pin 1 = 0
p = 78 pin 1 = 0
p = 79 pin 1 = 0
p = 80 pin 1 = 0
p = 81 pin 1 = 130
p = 82 pin 1 = 0
p = 83 pin 1 = 0
p = 84 pin 1 = 0
p = 85 pin 1 = 0
p = 86 pin 1 = 0
p = 87 pin 1 = 130
p = 88 pin 1 = 0
p = 89 pin 1 = 0
p = 90 pin 1 = 0
p = 91 pin 1 = 0
p = 92 pin 1 = 0
p = 93 pin 1 = 130
p = 94 pin 1 = 0
p = 95 pin 1 = 0
p = 96 pin 1 = 0
p = 97 pin 1 = 0
p = 98 pin 1 = 0
p = 99 pin 1 = 130
p = 100 pin 1 = 0
p = 101 pin 1 = 0
p = 102 pin 1 = 0
p = 103 pin 1 = 129
p = 104 pin 1 = 0
p = 105 pin 1 = 0
p = 106 pin 1 = 0
p = 107 pin 1 = 122
p = 108 pin 1 = 0
p = 109 pin 1 = 0
p = 110 pin 1 = 0
p = 111 pin 1 = 0
p = 112 pin 1 = 133
p = 113 pin 1 = 0
p = 114 pin 1 = 0
p = 115 pin 1 = 0
p = 116 pin 1 = 132
p = 117 pin 1 = 0
p = 118 pin 1 = 0
p = 119 pin 1 = 0
p = 120 pin 1 = 131
p = 121 pin 1 = 0
p = 122 pin 1 = 0
p = 123 pin 1 = 0
p = 124 pin 1 = 129
p = 125 pin 1 = 0
p = 126 pin 1 = 0
p = 127 pin 1 = 0
p = 128 pin 1 = 0
p = 129 pin 1 = 133
p = 130 pin 1 = 0
p = 131 pin 1 = 0
p = 132 pin 1 = 0
p = 133 pin 1 = 134
p = 134 pin 1 = 0
p = 135 pin 1 = 0
p = 136 pin 1 = 0
p = 137 pin 1 = 133
p = 138 pin 1 = 0
p = 139 pin 1 = 0
p = 140 pin 1 = 0
p = 141 pin 1 = 132
p = 142 pin 1 = 0
p = 143 pin 1 = 0
p = 144 pin 1 = 0
p = 145 pin 1 = 128
p = 146 pin 1 = 0
p = 147 pin 1 = 0
p = 148 pin 1 = 0
p = 149 pin 1 = 0
p = 150 pin 1 = 134
p = 151 pin 1 = 0
p = 152 pin 1 = 0
p = 153 pin 1 = 0
p = 154 pin 1 = 135
p = 155 pin 1 = 0
p = 156 pin 1 = 0
p = 157 pin 1 = 0
p = 158 pin 1 = 134
p = 159 pin 1 = 0
p = 160 pin 1 = 0
p = 161 pin 1 = 0
p = 162 pin 1 = 133
p = 163 pin 1 = 0
p = 164 pin 1 = 0
p = 165 pin 1 = 0
p = 166 pin 1 = 0
p = 167 pin 1 = 135
p = 168 pin 1 = 0
p = 169 pin 1 = 0
p = 170 pin 1 = 0
p = 171 pin 1 = 136
p = 172 pin 1 = 0
p = 173 pin 1 = 0
p = 174 pin 1 = 0
p = 175 pin 1 = 137
p = 176 pin 1 = 0
p = 177 pin 1 = 0
p = 178 pin 1 = 0
p = 179 pin 1 = 135
p = 180 pin 1 = 0
p = 181 pin 1 = 0
p = 182 pin 1 = 0
p = 183 pin 1 = 133
p = 184 pin 1 = 137
p = 185 pin 1 = 0
p = 186 pin 1 = 0
p = 187 pin 1 = 136
p = 188 pin 1 = 0
p = 189 pin 1 = 0
p = 190 pin 1 = 0
p = 191 pin 1 = 136
p = 192 pin 1 = 0
p = 193 pin 1 = 0
p = 194 pin 1 = 0
p = 195 pin 1 = 133
p = 196 pin 1 = 133
p = 197 pin 1 = 0
p = 198 pin 1 = 0
p = 199 pin 1 = 138
p = 200 pin 1 = 0
p = 201 pin 1 = 0
p = 202 pin 1 = 0
p = 203 pin 1 = 136
p = 204 pin 1 = 135
p = 205 pin 1 = 0
p = 206 pin 1 = 0
p = 207 pin 1 = 137
p = 208 pin 1 = 0
p = 209 pin 1 = 0
p = 210 pin 1 = 0
p = 211 pin 1 = 138
p = 212 pin 1 = 0
p = 213 pin 1 = 0
p = 214 pin 1 = 0
p = 215 pin 1 = 138
p = 216 pin 1 = 136
p = 217 pin 1 = 0
p = 218 pin 1 = 0
p = 219 pin 1 = 139
p = 220 pin 1 = 0
p = 221 pin 1 = 0
p = 222 pin 1 = 0
p = 223 pin 1 = 139
p = 224 pin 1 = 133
p = 225 pin 1 = 0
p = 226 pin 1 = 0
p = 227 pin 1 = 140
p = 228 pin 1 = 0
p = 229 pin 1 = 0
p = 230 pin 1 = 0
p = 231 pin 1 = 139
p = 232 pin 1 = 129
p = 233 pin 1 = 0
p = 234 pin 1 = 0
p = 235 pin 1 = 138
p = 236 pin 1 = 0
p = 237 pin 1 = 0
p = 238 pin 1 = 0
p = 239 pin 1 = 140
p = 240 pin 1 = 0
p = 241 pin 1 = 0
p = 242 pin 1 = 0
p = 243 pin 1 = 141
p = 244 pin 1 = 133
p = 245 pin 1 = 0
p = 246 pin 1 = 0
p = 247 pin 1 = 141
p = 248 pin 1 = 0
p = 249 pin 1 = 0
p = 250 pin 1 = 0
p = 251 pin 1 = 140
p = 252 pin 1 = 136
p = 253 pin 1 = 0
p = 254 pin 1 = 139
p = 255 pin 1 = 142
p = 256 pin 1 = 0

You're trying to sample a 15kHz signal with a 9kHz sample-rate method (analogRead).
You're also constraining your output by using a slow serial speed (960 characters per second)
You could reduce the ADC clock prescaler to increase the sample -rate, or reduce the ADC resolution.

Or just discard any 0 readings.

Mark

I realize that every cluster is when the pulse is on. It is not the zeros that are the problem.
I need to take the current reading only when the 15 khz pulse is on. This way it is reading the current when it is flowing.
If i could some how take the reading in the middle of the pulse, I think it would work.

Can you make the PWM signal trigger an adc read ?

...R

I realize that every cluster is when the pulse is on.

No, it's just when the phases coincide for a short while - you're not going to get consecutive samples from a single pulse with such a frequency disparity.

You could monitor the PWM with a digital read on the analogue pin, and then trigger the ADC conversion after a rising edge.
If you dig around the datasheet, you may even find a hardware-supported method.

Thats what I meant about the cluster, it is when the analogRead happens durring a pulse on as the two phases line up or over lap.

You could monitor the PWM with a digital read on the analogue pin, and then trigger the ADC conversion after a rising edge.

Wouldn't it be easier to monitor the timers counter and then trigger the read off of that?
Possibly with a interrupt?

Are you sure timer runs 15k? CS12 sets 256 prescaler:

1 0 0 clkI/O/256 (From prescaler)

You can synchronize sample and hold / start conversion events of the ADC to Timer1 , but you have to configure registers of the ADC to do so. Have a look here, as I don't recollect all details of the project at the moment:

For some unknown for me reason, Atmel designed TIMER 1 channel B to be an auto trigger source of the ADC, the same time to run TIMER 1 itself in CTC mode, channel A must be set. I simply “bind” two channels A and B in “parallel”, so both of them rise interrupt flag at the same moment, only A re-starts a TIMER 1, and B generates “start new conversion” event and calling ISR for “maintenance” – take a new sample

http://coolarduino.wordpress.com/2012/09/19/quasi-real-time-oscilloscope-remix/ code for AtMega32u4
and http://coolarduino.wordpress.com/2013/01/04/power-quality-meter/
code for AtMega328

That is exactly what I was looking to do, I was not sure what to call it. I did some further testing, and using a simple smoothing code that places the analogaRead results into an array and returns a running average every time works and I was able to control the current of my motor controller. Though this works, I want to look out synchronizing the ADC with the PWM and take reading that way. I am going to read what you linked, and do some further research on how to do this. I will post my results hear soon as I get a chance to do more testing.

Smoothing Code:

const int numReadings = 10;     // the number of samples
int readings[numReadings];      // the readings from the analog input
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average

void setup()

{
  // Setup Input / Output
  pinMode(1, INPUT);
               
  // initialize all the readings to 0: 
  for (int thisReading = 0; thisReading < numReadings; thisReading++) readings[thisReading] = 0;
}

void loop()

{
 total= total - readings[index];         
 readings[index] = analogRead(1); 
 total= total + readings[index];       
 index = index + 1;                    
 if (index >= numReadings) index = 0;                           
 average = total / numReadings;         
}
// initialize all the readings to 0:

Unnecessary - they were already zero.

After starting again today, I took a look at the code I was using to test, and Magician is right, the prescaler was set wrong. The low pass RC filter was not working because the freq was way lower than the cut off. After fixing the code I tryed again and the filter is now working as I get a straight line on the scope instead of square waves. :smiley:

I am going to see what the reads look like again.
Also AWOL , I copied and pasted the smooth code and did not have a chance to look at it that close. But I will today!

SUCCESS!!!
:smiley: :smiley:

With a RC filter cut off of 150 hz the analogRead is smooth and accurate.
Tested current limiting on controller program and it was flawless.
I am going to up the cut off freq to something that is still under the sampling freq but still higher than 150 hz so it is a little more responsive.
I need to fix final code and time the current check.