Victor Espinoza – Update 9

Write Data Function Implementation:

As discussed in a previous update, I was working on replacing the built-in analog write function with my own function that would be able to use pulse width modulation on any of the digital pins on the Arduino Uno.

For my implementation, the user can enter a pwm value between 0 -255, which determines the duty cycle for the desired pin (how long it will be set high compared to how long it will be set low). Depending on the duty cycle, I then need to set the pin high and low for the appropriate amount of time. This is achieved using timers, which I discussed in my Update #4.

There are 12 pins on the Arduino Uno that can safely be manipulated in this fashion (pins 2-13). Pins 0 and 1 can be changed, but they also double as the Rx and Tx pins, so I decided not to mess with these pins for now. Each pin can have a value of 1 or 0 at any given time, meaning that I need to have an array to keep track of each pin value. I am also going to initialize each pin to its off position. This is achieved using the following declaration:

extern volatile byte pinValue[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

I then need to keep the pin value high or low for the correct amount of time in order to achieve the appropriate duty cycle. To do this I use the following method:

// generate PWM on the different digital pins 
void analogWrite(byte pinNum, byte pinVal) {  
   if (pinNum >= 2 && pinNum <= 13 && pinVal >= 0 && pinVal < 265) {  
      pinNum -= 2;  
      pinVal[pin-2] = pinVal; % get proper pinValue index
      if (pinVal == 0)  
         if(pinNum <= 7) // updating pins 2 - 7 (PORTD)
            PORTD = PORTD & (0 >> pinNum) // sets pin low
         else // updating pins 8 - 13 (PORTB)
            PORTB = PORTB & (0 >> pinNum-8) // sets pin low
   } //end if
} //end analogWrite(...)

I also use the following method to aid in this:

// Routine to emit the PWM on the pins  
void pulse() {  
   static int counter = 0;  
   for(int i = 0; i < 12; i += 1) {  
      if (pinVal[i]){ 
         if(i+2 <= 7) // updating pins 2 - 7 (PORTD)
            PORTD = PORTD & ((pinVal[i]>counter)>>i+2) // update pin value 
         else // updating pins 8 - 13 (PORTB)
            PORTB = PORTB & ((pinVal[i]>counter)>>i+2) // update pin value 
      } // end if
      counter = ++counter > PERIOD ? 0 : counter; 
   } //end for
} //end pulse()

The final step is to generate a timer interrupt that constantly calls the pulse() routine.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s