From 05242cd3068f9715802eb8941ba700104e5424ca Mon Sep 17 00:00:00 2001 From: "M. Stokroos" Date: Tue, 3 Dec 2019 10:56:57 +0100 Subject: [PATCH] added example varDutyT1 --- README.md | 11 ++- sketches/varDutyT1/varDutyT1.ino | 127 +++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+), 4 deletions(-) create mode 100644 sketches/varDutyT1/varDutyT1.ino diff --git a/README.md b/README.md index cf3429c..ac31029 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,10 @@ This repository contains Arduino sketches and Arduino libraries maintained by th ## Sketches -- **Blinky** +**Blinky** A hello world example used to play along with Git. -- **Nexus_Omni4WD** +**Nexus_Omni4WD** Firmware for the Nexus Omni4WD wheel base for setting the wheel speeds independently. It is used to control the robot under ROS. ![ ](figures/NexusOmni4WD.png "Nexus Omni 4WD") @@ -24,14 +24,17 @@ The Arduino controller 10009 with io expansion shield on the Omni4WD is Duemila *extra/nexuscontrol* Script for controlling the Nexus with ROS. -- **RoFish** +**RoFish** A CPG-based locomotion control example of a robotic fish. ![ ](figures/animation.gif "Robotic Fish") -- **adaptiveFreqOsc** +**adaptiveFreqOsc** An adaptive frequency oscillator example with Arduino. +**varDutyT1** +A sketch for varying (modulating) the duty-cycle of the PWM on the UNO-output pins 9 and 10 via the analog A0 input. The PWM frequency and update rate(!) = 15.625kHz. Resolution is 10-bits. + ## Libraries Currently there are no libraries available. diff --git a/sketches/varDutyT1/varDutyT1.ino b/sketches/varDutyT1/varDutyT1.ino new file mode 100644 index 0000000..0a1457b --- /dev/null +++ b/sketches/varDutyT1/varDutyT1.ino @@ -0,0 +1,127 @@ +/* + * File: varDutyT1.ino + * Purpose: Varying the duty-cycle of the PWM on output pins 9 and 10 via the analog A0 input. Update rate: 15.625kHz, resolution: 10-bits. + * + * Version: 1.0.0 + * + * By: M. Stokroos + * + * Date: 02-12-2019 + * + */ + +// Library to be included for fast digital I/O when observing the timing with an oscilloscope. +//#include // library for high performance digital reads and writes by jrraines + // see http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1267553811/0 + // and http://code.google.com/p/digitalwritefast/ + + +#define LPERIOD 500000 // the main loop period time in us. In this case 500ms. +#define PIN_LED 13 // PLL locking status indicator LED +#define PIN_PWMA 9 // Timer1 OCR1A 10-bit PWM +#define PIN_PWMB 10 // Timer1 OCR1B 10-bit PWM +#define PIN_DEBUG 4 // test output pin + +// global vars +volatile int adcVal; +unsigned long nextLoop; + + +// ****************************************************************** +// Setup +// ****************************************************************** +void setup(){ + cli(); // disable interrupts + pinMode(PIN_LED, OUTPUT); + pinMode(PIN_PWMA, OUTPUT); + pinMode(PIN_PWMB, OUTPUT); + pinMode(PIN_DEBUG, OUTPUT); + + // initialize ADC for continuous sampling mode + DIDR0 = 0x3F; // digital inputs disabled for ADC0D to ADC5D + bitSet(ADMUX, REFS0); // Select Vcc=5V as the ADC reference voltage + bitClear(ADMUX, REFS1); + bitClear(ADMUX, MUX0); // selecting ADC CH# 0 + bitClear(ADMUX, MUX1); + bitClear(ADMUX, MUX2); + bitClear(ADMUX, MUX3); + bitSet(ADCSRA, ADEN); // AD-converter enabled + bitSet(ADCSRA, ADATE); // auto-trigger enabled + bitSet(ADCSRA, ADIE); // ADC interrupt enabled + bitSet(ADCSRA, ADPS0); // ADC clock prescaler set to 128 + bitSet(ADCSRA, ADPS1); + bitSet(ADCSRA, ADPS2); + bitClear(ADCSRB, ACME); // Analog Comparator (ADC)Multiplexer enable OFF + bitClear(ADCSRB, ADTS0); // triggered by Timer/Counter1 Overflow + bitSet(ADCSRB, ADTS1); + bitSet(ADCSRB, ADTS2); + bitSet(ADCSRA, ADSC); // start conversion + + /* configuring TIMER1 for PWM-mode 7 */ + // prescaler = 1: + bitSet(TCCR1B, CS10); + bitClear(TCCR1B, CS11); + bitClear(TCCR1B, CS12); + // mode 7: + bitSet(TCCR1A, WGM10); + bitSet(TCCR1A, WGM11); + bitSet(TCCR1B, WGM12); + bitClear(TCCR1B, WGM13); + //set output compare + bitClear(TCCR1A, COM1A0); // Compare Match PWM 9 + bitSet(TCCR1A, COM1A1); + bitSet(TCCR1A, COM1B0); // Compare Match PWM 10 - inverted channel + bitSet(TCCR1A, COM1B1); + // enable TIMER1 compare interrupt + bitSet(TIMSK1, TOIE1); // enable Timer1 Interrupt + sei(); // global enable interrupts + nextLoop = micros() + LPERIOD; // Set the loop timer variable for the next loop interval. +} + + + + +// ****************************************************************** +// Main loop +// ****************************************************************** +void loop(){ + // do nothing here except for flashing the LED... + + digitalWrite(PIN_LED, !digitalRead(PIN_LED)); + + while(nextLoop > micros()); // wait until the end of the time interval + nextLoop += LPERIOD; // set next loop time at current time + LOOP_PERIOD +} + + + + +/* ****************************************************************** +* ADC ISR. The ADC is triggered by Timer1. +* *******************************************************************/ +ISR(ADC_vect){ + //digitalWriteFast(PIN_DEBUG, HIGH); //for checking the interrupt frequency + + // read the current ADC input channel + adcVal=ADCL; // store low byte + adcVal+=ADCH<<8; // store high byte + + // write out 10bit PWM output registers A&B (pin9 and pin10). + OCR1AH = adcVal>>8; //MSB + OCR1AL = adcVal; //LSB + //(inverted) output: + OCR1BH = OCR1AH; //MSB + OCR1BL = OCR1AL; //LSB + + //digitalWriteFast(PIN_DEBUG, LOW); +} + + + + +/* ****************************************************************** +* Timer1 ISR +*********************************************************************/ +ISR(TIMER1_OVF_vect) { +//empty ISR. Only used to trigger the ADC. +}