FreqMeasure clash with Servo

Hello,

I am creating a program which translates low (below 60Hz) frequencies to graphical display.

Got it working perfectly to give a bar graph on LCD, then added PWM out to a vintage AVO meter to give a more tactile output.

Was looking to use a large display with moving hand with a servo. Added a servo function and mapped in the same way i done with the PWM out and no servo function.

From the top down i added sections of the program untill the servo wouldnt initialise. have now realised that once i do "FreqMeasure.begin()", the servo stops working, as code below.

void setup() {
  delay(100);
   
  Serial.begin(57600);
  lcd.createChar(0, p1);
  lcd.createChar(1, p2);
  lcd.createChar(2, p3);
  lcd.createChar(3, p4);
  lcd.createChar(4, p5);
  
  Wire.begin();
  RTC.begin();
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    //RTC.adjust(DateTime(__DATE__, __TIME__));
  delay(100);
  }
  
  myServo.attach(A2);
  myServo.write(90);
    delay(15);
  lcd.begin(16, 2);
  FreqMeasure.begin();
}

If i comment out the FreqMeasure.begin();, servo works.

Ive tried on various pins, and its the same on any output pin.

By not working, i mean not even any resistance to turn the servo, there is no output on the pin at all.

Possibly a timer conflict? Any resolution possible?

Thanks,
Stuart

As you did not post ALL your code there's no way to tell which servo code your using, so no way to help you.

Mark

You seem to have the servo connected to an analogue pin - can that work?

...R

Hi,

The code pasted was the test code to find at which thing added stops it working by adding it in almost line by line. As it stops working before the rest of the code in the i didnt put that all in.

For servo, i am just myServo.write(angle); where angle is the frequency range of interest mapped against 0-179.

Interestingly, FreqMeasure.begin() stops servo from working, however the FreqMeasure functions still work perfectly. Its as if its using and getting priority over something servo uses. I feel if i could find this and get a work around that would solve things.

Perhaps i can drive the servo by code as opposed to use the library?

For clarity, the test code which writes 90deg to the servo is:

#include <Wire.h>
#include "RTClib.h"
#include <FreqMeasure.h>
#include <LiquidCrystal.h>
#include <Servo.h>

#define lenght 16.0

double percent=100.0;
unsigned char b;
unsigned int peace;
Servo myServo;
RTC_DS1307 RTC;

//LiquidCrystal lcd(5, 4, 3, 2, 1, 0);
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
byte p1[8] = {
  0x10,
  0x10,
  0x10,
  0x10,
  0x10,
  0x10,
  0x10,
  0x10};

byte p2[8] = {
  0x18,
  0x18,
  0x18,
  0x18,
  0x18,
  0x18,
  0x18,
  0x18};

byte p3[8] = {
  0x1C,
  0x1C,
  0x1C,
  0x1C,
  0x1C,
  0x1C,
  0x1C,
  0x1C};

byte p4[8] = {
  0x1E,
  0x1E,
  0x1E,
  0x1E,
  0x1E,
  0x1E,
  0x1E,
  0x1E};

byte p5[8] = {
  0x1F,
  0x1F,
  0x1F,
  0x1F,
  0x1F,
  0x1F,
  0x1F,
  0x1F};

const int sensorPin = A0;  //temperature sensor input
const int ledred =  13;    // RED (on) & onboard LED
const int ledgrn = 9;      // GREEN (off) LED
const int FOutPIN = 6;     // PWM output for analoge frequency
int analOut;
int angle;
const int ScrnBtn = 7;
const int buttonPin = A1;  //analoge button input
int ScrnBtnState = 0;
int ScrnBtnCount = 0;
int ScrnBtnLastState = 0;
int ScrnBtnMax = 4;

int ctrlMode = 1;          // 0 = Heating mode,  1 = Cooling mode (swaps on off and sets on off hysterysis to negative value)
int onTime = 0;            // ms of minimum on time
int offTime = 0;           // ms of minimum off time
double lastMillis = 0;        // last millis timer for comparisson next time around
double lastSec = 0;        // last millis timer for comparisson next time around (serial output)

unsigned long Timer;


double Fsum=0;
int Fcount=0;

double Tsum=0;
int Tcount=0;

float temperature;
double sign=0;
double TempSet=25;           // Desured setting
double TempSetUse=0.0;       // Variable selected from next three based on grid frequency
double Thyst=2;              // start/stop differential under normal frequency  <<<<<<<<<<<<< ADJUSTABLE
double THyst=0;              // Used for heating & cooling calculations

double frequency;

double TAdjust=0;            // Adjustment factor identified AFTER frequency point.  This will be one of the 3 below.
double TAsjustLast=0;        // Used to data log events which result in a setpoint change
double adjustOp=0.50;        // "Operating" limit, Minor frequency variance, temperature differential to use
double adjustSt=1.00;        // "Statutory" limit, Intermediate frequency variance, temperature differential to use
double adjustEm=1.50;        // "Emergancy" limit, Major frequency variance, temperature differential to use

double FreqSet=50.00;        // Normal frequency
double FHystOp=0.1;          // Operating limits (49.8 - 50.2Hz)
double FHystSt=0.2;          // Statutory limits (49.5 - 51.5Hz)
double FHystEm=0.5;          // Near black out (-49 to 51+Hz), disregard temperature

double FNegOffset = -0.055;   //-0.055
double FPosOffset = -0.056;   //-0.056
double FOffset = 0;           // used for calculating accounting for sign


void setup() {
  delay(100);
   
  Serial.begin(57600);
  lcd.createChar(0, p1);
  lcd.createChar(1, p2);
  lcd.createChar(2, p3);
  lcd.createChar(3, p4);
  lcd.createChar(4, p5);
  
  Wire.begin();
  RTC.begin();
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    //RTC.adjust(DateTime(__DATE__, __TIME__));
  delay(100);
  }
  
  myServo.attach(A2);
  myServo.write(90);
    delay(15);
  lcd.begin(16, 2);
//  FreqMeasure.begin();
}
  void loop() {
    
  }

The test code which doesnt result in 90deg being written to the servo is:

#include <Wire.h>
#include "RTClib.h"
#include <FreqMeasure.h>
#include <LiquidCrystal.h>
#include <Servo.h>

#define lenght 16.0

double percent=100.0;
unsigned char b;
unsigned int peace;
Servo myServo;
RTC_DS1307 RTC;

//LiquidCrystal lcd(5, 4, 3, 2, 1, 0);
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
byte p1[8] = {
  0x10,
  0x10,
  0x10,
  0x10,
  0x10,
  0x10,
  0x10,
  0x10};

byte p2[8] = {
  0x18,
  0x18,
  0x18,
  0x18,
  0x18,
  0x18,
  0x18,
  0x18};

byte p3[8] = {
  0x1C,
  0x1C,
  0x1C,
  0x1C,
  0x1C,
  0x1C,
  0x1C,
  0x1C};

byte p4[8] = {
  0x1E,
  0x1E,
  0x1E,
  0x1E,
  0x1E,
  0x1E,
  0x1E,
  0x1E};

byte p5[8] = {
  0x1F,
  0x1F,
  0x1F,
  0x1F,
  0x1F,
  0x1F,
  0x1F,
  0x1F};

const int sensorPin = A0;  //temperature sensor input
const int ledred =  13;    // RED (on) & onboard LED
const int ledgrn = 9;      // GREEN (off) LED
const int FOutPIN = 6;     // PWM output for analoge frequency
int analOut;
int angle;
const int ScrnBtn = 7;
const int buttonPin = A1;  //analoge button input
int ScrnBtnState = 0;
int ScrnBtnCount = 0;
int ScrnBtnLastState = 0;
int ScrnBtnMax = 4;

int ctrlMode = 1;          // 0 = Heating mode,  1 = Cooling mode (swaps on off and sets on off hysterysis to negative value)
int onTime = 0;            // ms of minimum on time
int offTime = 0;           // ms of minimum off time
double lastMillis = 0;        // last millis timer for comparisson next time around
double lastSec = 0;        // last millis timer for comparisson next time around (serial output)

unsigned long Timer;


double Fsum=0;
int Fcount=0;

double Tsum=0;
int Tcount=0;

float temperature;
double sign=0;
double TempSet=25;           // Desured setting
double TempSetUse=0.0;       // Variable selected from next three based on grid frequency
double Thyst=2;              // start/stop differential under normal frequency  <<<<<<<<<<<<< ADJUSTABLE
double THyst=0;              // Used for heating & cooling calculations

double frequency;

double TAdjust=0;            // Adjustment factor identified AFTER frequency point.  This will be one of the 3 below.
double TAsjustLast=0;        // Used to data log events which result in a setpoint change
double adjustOp=0.50;        // "Operating" limit, Minor frequency variance, temperature differential to use
double adjustSt=1.00;        // "Statutory" limit, Intermediate frequency variance, temperature differential to use
double adjustEm=1.50;        // "Emergancy" limit, Major frequency variance, temperature differential to use

double FreqSet=50.00;        // Normal frequency
double FHystOp=0.1;          // Operating limits (49.8 - 50.2Hz)
double FHystSt=0.2;          // Statutory limits (49.5 - 51.5Hz)
double FHystEm=0.5;          // Near black out (-49 to 51+Hz), disregard temperature

double FNegOffset = -0.055;   //-0.055
double FPosOffset = -0.056;   //-0.056
double FOffset = 0;           // used for calculating accounting for sign


void setup() {
  delay(100);
   
  Serial.begin(57600);
  lcd.createChar(0, p1);
  lcd.createChar(1, p2);
  lcd.createChar(2, p3);
  lcd.createChar(3, p4);
  lcd.createChar(4, p5);
  
  Wire.begin();
  RTC.begin();
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    //RTC.adjust(DateTime(__DATE__, __TIME__));
  delay(100);
  }
  
  myServo.attach(A2);
  myServo.write(90);
    delay(15);
  lcd.begin(16, 2);
  FreqMeasure.begin();
}
  void loop() {
    
  }

Confused here, any insight is appreciated.

Robin2:
You seem to have the servo connected to an analogue pin - can that work?

...R

Hello, Didn't think it could but I found posts where it was suggested. Have proven myself by actuating the servo properly from the Analogue pin. Have also tried on pins 10 & 6 which were free. Just happens the Analogue pin was the last i tried so have not moved back to digital

On the 3 tried, the results are the same each time. Servo works with no FreqMeasure, servo doesnt work with FreqMeasure.

Thanks,
Stuart

Looks like servo and freqMeasure are using the same timer try using newServo (?) check in palyground. Yes you can just bit bang a servo start by using blink without delay.

Mark

Hi,

On the new servo, are you referring to this? Arduino Playground - Servo

Ive got the blink without delay type thing running already in this program as delays cause a loss of frequency resolution so ive got a total of about 1ms for an analog read and thats it (expect the program time of course).

Have not bitbanged yet, i assume a method such as shown here, but using the delay-less timing system perhaps? http://forum.arduino.cc/index.php/topic,146884.0.html

On the new servo, are you referring to this? http://playground.arduino.cc/ComponentLib/Servo

Looks like it’s worth a go but had a feeling that theres was a lib called newServo.

Never use delay in your programs EVER. Look at FSM’s (playground).

Have not bitbanged yet, i assume a method such as shown here, but using the delay-less timing system perhaps? http://forum.arduino.cc/index.php/topic,146884.0.html

Yes right idea. But never use delay().

Mark

There is a library called ServoTimer2 which I have used when I wanted the usual timer to be free.

...R

Hello,

Got a chance to get back into this. As far as i can tell ServoTimer2 and newServo all use the 16-bit timer ICP1. Looking into the /ulti/capture.lib within FreqMeasure, it uses ICP1 on pin 8 for the frequency measurement.

As i don't really need 16-bit resolution for the timer in FreqMeasure, i could perhaps use ICP2. ICP0 as i understand is used by the millis() etc.

Am i correct in saying on an Uno that ICP2 is not taken to a pin? Been having a look and it would appear perhaps a mega is needed for another timer interrupt pin?

OK, been a little dumb...

Been trying to find a way to change servo to use timer 2. And it dawned on me that the servotimer2 library does just as the name suggests!

Woops!

Should not try to program after a long day at work and i sit and miss the obvious!

Anyway, tried servotimer2 and it appears to work, only thing is i broke a cog in the servo which came with the starter pack by applying too much force. Another beefier servo ordered so will see how that works.