SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By Mee_n_Mac
#141206
Sometimes I can see drops at about every 10 samples (=40 msec, =25 Hz) and other times it's more often (every 3'rd sample) and then other times it's missing. I don't know what to make of the drops yet.
By Mee_n_Mac
#141209
dkulinski wrote:If you discard the values above 640 do you see a pattern?

Dan
Sometimes it's there (ever 10 samples) but look at what happens around time = 3200 - 3400. Maybe it really needs to be sampled every 1 msec to catch the troughs. Afterall the working SW seems to time a cycle and it samples faster than that ... perhaps the "secret" to it's success.

Here's a revised FFT with the bins labeled per their frequency. You can see a component near the expected cyclic rate but it doesn't jump out loudly from the other "stuff". I've not plotted the uber strong DC component (because we don't care about it).
Log1FFT.jpg
You do not have the required permissions to view the files attached to this post.
Last edited by Mee_n_Mac on Thu Mar 15, 2012 1:31 pm, edited 4 times in total.
By dkulinski
#141213
It can definitely be upped, but I don't know if it can be pushed to 1 sample every 1ms without sending binary over the serial link. And then at that point you have to do some post conversion. I really thought about that for this run but I didn't figure it would be worth the mess.

Right now I broke down the needed rates by output and sample rate.

So up to 6 characters for the time (that gives us 1000 seconds) and 4 for the ADC and one for the tab and one for the new line. That gives us 12 bytes per output. I think I calculated this much higher initially because my math isn't quite working out. So if we are doing 38400bps, that would be 4800 bytes per second or 400 samples per second. That would max out the readings at 16 times per cycle at 25hz.

Bumping up to 115200bps, we could squeeze in 1200 samples per second or 48 samples per cycle at 25hz.

Moving to binary we could get down to 6 bytes (4 bytes for time, 2 bytes for ADC) per sample (and a lot of reduced overhead from the conversions). This would allow the readings to come in at 96 times per cycle (at 115200 bps).

unfortunately I am not sure how to record a binary stream from the arduino serial port. I have never tried with putty. After you get the data a quick Python script would allow a transform from binary to something human readable. It may be worth a try. Nearly 100 readings per cycle is going to be pretty darn illuminating. Now, since I don't have an AEG we have to convince Static that this is the way to go!
By Mee_n_Mac
#141214
dkulinski wrote:It can definitely be upped, but I don't know if it can be pushed to 1 sample every 1ms without sending binary over the serial link.
What if you don't send the time ? I mean "we know" the sampling is being done every msec so what does that tell us ? Perhaps have an option to send the time or the sample data so the time interval can be verified first. Afterwards just send the sampled current data. BTW does the millis timer/count get reset to start so the number of characters to be sent for time is small, at least at the start and for a short recording period to verify the timing ?
By dkulinski
#141215
I wonder how close we are getting to the limits on the ATMega chips. I'll have to sit down later tonight and ponder how fast we can dump to the serial line. What kind of resolution are you thinking is necessary?
By Mee_n_Mac
#141216
dkulinski wrote:I wonder how close we are getting to the limits on the ATMega chips. I'll have to sit down later tonight and ponder how fast we can dump to the serial line. What kind of resolution are you thinking is necessary?
I think an msec would be sufficient. Notice you never see 2 consecutive samples that are "low". But at 120 usec for an A/D conversion plus ISR latency and code run time and ??? ... can 1kHz sampling be done ? I think so and I think the UART is pipelined/buffered (so the UART doesn't have to empty before the next sample, though I don't know what the Arduino library function does in that regard). 5 characters at 10 bits/char means a min baud rate of 50 bits/msec or 50K baud.
By dkulinski
#141217
Ah I get it now. I am pretty sure that the built in UART is buffered also. So yes, setting a timer to dispatch only the adc readings would be 4 characters (3 for the adc plus new line). We could cut that down to 3 characters and post process the output. In anycase, my code should be pretty easy to change.

One thing I would do is just have the arduino automatically trigger the motor after a short delay that can be controlled.
By Mee_n_Mac
#141218
dkulinski wrote:One thing I would do is just have the arduino automatically trigger the motor after a short delay that can be controlled.
Or enable the ISR after the trigger has been sensed as pulled.
By dkulinski
#141232
Quick shot at new code:
Code: Select all
        /*
          BasicAmperageMonitor-Feb-27-2012
         

         
         The circuit:
         * LED on board at pin 13
         * Motor control on pin 3 (PWM pin)
         * pushbutton attached to pin 7 from +5V
         * 10K resistor attached to pin 7 from ground
         * ADC on analog pin 0
         
         Serial settings:
         Bits per second 38400
         

        */

        #include <TimerOne.h>

        const int buttonPin = 7;  //Trigger switch attached to digital pin 7
        const int ledPin = 13;  //onboard LED on pin 13
        const int MotorPin = 3; //Motor drive pin (on MOSFET) connected to PWM pin at pin 3
        const int CurrentSensor = 0;  //Current flow sensor attached to Analog 0
        const int MotorSpeed = 255;  //PWM value for motor, max 255
       
        int buttonState = 0;  // Trigger button state
        volatile int IMain = 0; // Direct ADC reading from current sensor
        long ReadAmpsInterval = 1000; // This will provide 10 readings per AEG cycle



        void setup() {
          Serial.begin(115200); // High output rate to accept about 25 samples per motor cycle
          pinMode(MotorPin, OUTPUT);  //Set the MotorPin as an output
          analogWrite(MotorPin, 0);  // make sure that the MotorPin is Off
         
          pinMode(ledPin, OUTPUT);  // Set the LED Pin as an output
          pinMode(buttonPin, INPUT);  // set the trigger pin as an input
         
          Timer1.initialize(ReadAmpsInterval);  //set up the interrupt timer to read at the ReadAmpsInterval
          Timer1.attachInterrupt(ReadAmps);  //The function to call every interval
          
        }


        void loop() {
         
          /* A simple loop to drive the motor while the trigger is held down */
         
           buttonState = digitalRead(buttonPin);
           while(buttonState == HIGH) {
             analogWrite(MotorPin, MotorSpeed);

             digitalWrite(ledPin,HIGH);
           }
           
           analogWrite(MotorPin, 0);
           digitalWrite(ledPin, LOW);
        }


        void ReadAmps()          //this is the interrupt function
        {
          IMain = analogRead(CurrentSensor);   //simply reads the CurrentSensor and stores the value in IMain
         
          /* Write out the sensor reading, MSB then LSB */
          //Serial.print(IMain,DEC);
         Serial.write(48 + IMain/100);
         Serial.write(48 + (IMain%100)/10);
         Serial.write(48 + IMain%10);

          /* Send a tab */
          //Serial.write(0x09);
         
          /* Write out the millisecond count (repeats after 50 days of run time) */
         // unsigned long currentTime = millis();
          //Serial.print(currentTime,DEC);
         
          /* Send a carriage return */
          Serial.write(0x0D);
        }

I changed the serial code so it doesn't have to go through a conversion. This should be a bit faster than Serial.print as it doesn't have to find the size of the string (we know it to be 3 digits long) and I simply add the number 48 to produce the ascii equivalent.

Plug in this code and pull the trigger. It may lock the firing sequence down again. I didn't have it activate only when the trigger is pulled as there is no switch debouncing.

Dan
By Mee_n_Mac
#141244
I hope the 1 msec sampling proves illuminating. I wonder why there should be a large, if brief, current "drop-out" once a cycle but it suffices that it consistently occurs for SD5 to use it for timing.
By dkulinski
#141258
Is it bad that I am like a kid at christmas waiting for this data? The fact that we can dig into these system with cheap electronics is exciting. Further, the fact that we can understand and ultimately control the previously dumb electronics is doubly exciting. The fact that Static is willing to be so open about his process is great. I can't wait until I can participate more directly with my own hardware.

I honestly can't wait to get into this myself. I am hoping to get AEGs for both my son and I, and I would love to drop in some electronics. I may forgo the chronometer unless I can attach it to the end of the barrel rather than modifying the barrel itself. I would love to have the ability to add these items and be able to remove them to keep the AEG stock when needed.

Looking forward to the data. Hopefully it wasn't as noisy and inconclusive as what we have now.

Dan
By StaticDet5
#141259
OK, here's the latest try. I'm posting immediately, before looking at it. I need to examine the code and figure out what's it doing, in relation to the output. I'm also going to try looking at it with Excel
You do not have the required permissions to view the files attached to this post.
  • 1
  • 9
  • 10
  • 11
  • 12
  • 13
  • 32