1

I have written code to read temperatures on a motor which also has pulse feedback to see speed, (one hall sensor) and my previous version of the code does work fine, however when i add example frequency code from codebender into my code it doesn't give feedback on the frequency. Standalone the frequency code works fine. Is there any obvious failure in the code or is there just some conflict between files in library?

Trying to return RPM into the SD card results in 0.00. And the temperature measurements goes into switching between 85C and -127C.

Equipment: Arduino Nano, DS18B20, 2x16 LCD, Homemade SD shield, motor with internal motordriver.

Here is my code:

#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>
#include <SD.h>
#include <FreqMeasure.h>

// Data wire is plugged into pin 9 on the Arduino
#define ONE_WIRE_BUS 9

// Setup a oneWire instance to communicate with any OneWire devices 
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

float temperature1, temperature2, temperature3;
double RPM;
void setup(void)
{
  // start serial port
  Serial.begin(57600);
  FreqMeasure.begin();
  Serial.println("Dallas Temperature IC Control Library Demo");
  // Start up the library
  lcd.begin(16, 2);
  sensors.begin();
  Serial.print("Initializing SD card...");      // Initialize SD card

  if (!SD.begin(10)) {                          
    Serial.println("initialization failed!");   // Initialize SD card failed
    return;                                     
  }
  Serial.println("initialization done.");       // Initialize SD card done
}

double sum=0;
int count=0;

void loop(void)
{
  if (FreqMeasure.available()) {
    // average several reading together
    sum = sum + FreqMeasure.read();
    count = count + 1;
    if (count > 30) {
      double frequency = F_CPU / (sum / count);
      RPM=frequency*60;
      sum = 0;
      count = 0;
    }
  }

  unsigned long curMillis = millis();  
  unsigned long curSeconds = curMillis/1000;   // Get current seconds
  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus
  Serial.print(" Requesting temperatures...");
  sensors.requestTemperatures(); // Send the command to get temperatures
  Serial.println("DONE");
  temperature1=sensors.getTempCByIndex(0);
  temperature2=sensors.getTempCByIndex(1);
  temperature3=sensors.getTempCByIndex(2);
  logData();
  Serial.print("Temperature for Device 1 is: ");
  Serial.print(sensors.getTempCByIndex(0)); // Why "byIndex"? 
  Serial.print("Temperature for Device 2 is: ");
  Serial.print(sensors.getTempCByIndex(1));
  Serial.print("Temperature for Device 3 is: ");
  Serial.println(sensors.getTempCByIndex(2));

  lcd.setCursor(0, 0);
  lcd.print("T1=");
  lcd.setCursor(3, 0);
  lcd.print(sensors.getTempCByIndex(0));
  lcd.setCursor(8, 0);
  lcd.print("T2=");
  lcd.setCursor(11, 0);
  lcd.print(sensors.getTempCByIndex(1));
  lcd.setCursor(0, 1);
  lcd.print("T3=");
  lcd.setCursor(3, 1);
  lcd.print(sensors.getTempCByIndex(2));
  lcd.setCursor(8, 1);
  lcd.print("S=");
  lcd.setCursor(10, 1);
  lcd.print(curSeconds);
    // You can have more than one IC on the same bus. 
    // 0 refers to the first IC on the wire

}

void logData() {
  Serial.print("Temperature1 = ");   Serial.print(temperature1);    // Printing to serial communication
  Serial.print(" C, Temperature2 = ");  Serial.print(temperature2);       // Printing to serial communication
  Serial.print(" C, Temperature3 = ");  Serial.print(temperature3);       // Printing to serial communication
  Serial.println(" C");                                           // Printing to serial communication
  Serial.println(RPM);
  unsigned long curMillis = millis();          // Get current time
  unsigned long curSeconds = curMillis/1000;   // Get current seconds

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File myFile = SD.open("LOG.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to LOG.txt...");                        // Printing to serial communication
    myFile.print("Time = "); myFile.print(curSeconds);            // Printing to log file on sd card
    myFile.print(" Temperature1 = "); myFile.print(temperature1);   // Printing to log file on sd card
    myFile.print(" Temperature2 = "); myFile.print(temperature2);         // Printing to log file on sd card
    myFile.print(" Temperature3 = "); myFile.print(temperature3);       // Printing to log file on sd card
    myFile.print(" RPM = "); myFile.println(RPM);       // Printing to log file on sd card
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening LOG.txt");                      // Error either SD card not connected or not detected
  }
  delay(1000);
}
  • if (FreqMeasure.available() == false) then RPM is not initialised but it is used later on, this will produce odd results, but not the fault you see. Also why keep calling sensors.getTempCByIndex(2) when you have written the values to Temperature3? – Code Gorilla Sep 21 '16 at 13:21
  • The repetition of 'sensors.getTempCByIndex(2)' is just a minor fault from my previous version of the code. And i have checked the 'FreqMeasure.available()' and it is false in the start but goes to some number between 1-11 during motor running, so should start running then. – Gísli Trausti Jóhannesson Sep 21 '16 at 13:42
  • Gísli - Sorry neither of the things I mentioned will fix you problem, I should have said that. Yes sensors.getTempCByIndex(2) is a minor thing. The RPM is going to cause problems. I will do an answer so I can explain. – Code Gorilla Sep 21 '16 at 15:32
1

I believe there is a conflict bewteen the code relative to the SD card, which uses SPI and the use of timer1 within FreqMeasure.

My advice is to temporarily remove the code for the SD card and write that data onto the serial console: if the data displays correctly on the serial monitor than you have an indication the issue is in there.

The problem with SPI and time based interrupts is the latter might prevent the SPI communication to properly complete.

  • Thanks for the idea, will check it out and then post if it is the problem. – Gísli Trausti Jóhannesson Sep 21 '16 at 13:43
  • The conflict is between the (OneWire.h DallasTemperature.h) and the FreqMeasure.h, tried the SD.h and all its variables and that was not the conflict however when i tried disabling the temperatures then the frequency worked fine. – Gísli Trausti Jóhannesson Sep 22 '16 at 6:35
0

This is an explanation of the issue with the RPM variable in the code, its not an answer, but it needs formatting to explain it clearly.

double RPM;
...
if (FreqMeasure.available()) {
...
  RPM=frequency*60;
...
}
...
Serial.println(RPM);

It is possible that RPM is going to be written to Serial.println() before it has a value set.

In this case it is very unlikely to cause anything more than 'garbage' to be printed, but it could be much worse. So I think if you initialised the RPM variable to 0.0 when you declare it it would be good practice.

0

From what i have tested myself towards then it seems that the problem with this code is that OneWire.h and DallasTemperature.h are the problem when combined with FreqMeasure.h, so i found a way to use the A0 as RPM reader. So the answer to the question is that those libraries are uncompatible, and with the following code it is possible to read RPM, temperature and write to SD.

My code works with the added A0 as RPM reader.

#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>
#include <SD.h>

// Data wire is plugged into pin 9 on the Arduino
#define ONE_WIRE_BUS 9

// Setup a oneWire instance to communicate with any OneWire devices 
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

float temperature1, temperature2, temperature3;
double RPM=0.0;
//storage variables
byte newData = 0;
byte prevData = 0;
//freq variables
unsigned int timer = 0;
unsigned int period = 0;
double frequency;

void setup(void)
{
  cli();  //disable interrupts
  ADCSRA = 0; //clear register
  ADCSRB = 0; //clear register

  ADMUX|=(1<<REFS0);  //Set reference voltage
  ADMUX|=(1<<ADLAR);  //left align the ADC value so we can read highest 8 bits from the ADCH register only
  ADCSRA|=(1<<ADPS2)|(1<<ADPS0);  //set ADC clock with 32 prescaler- 16mHz/32=500kHz
  ADCSRA|=(1<<ADATE); //enable auto trigger
  ADCSRA|=(1<<ADIE);  //enable interrupts when measurement is complete
  ADCSRA|=(1<<ADEN);  //enable ADC
  ADCSRA|=(1<<ADSC);  //start ADC measurement
  sei();  //enable interrupts

  // start serial port
  Serial.begin(57600);
  Serial.println("Dallas Temperature IC Control Library Demo");
  // Start up the library
  lcd.begin(16, 2);
  sensors.begin();
  Serial.print("Initializing SD card...");      // Initialize SD card

  if (!SD.begin(10)) {                          
    Serial.println("initialization failed!");   // Initialize SD card failed
    return;                                     
  }
  Serial.println("initialization done.");       // Initialize SD card done
}
ISR(ADC_vect){  //when new ADC value ready
  prevData = newData; //store previous value
  newData = ADCH; //get value from A0
  if(prevData<127 && newData>=127){ //if increasing and crossing midpoint
    period = timer; //get period
    timer = 0;  //reset timer
  }
  timer++;  //increment timer at rate of 38,5kHz
}

void loop(void)
{
  frequency = 38462/period; //timer rate/period
  RPM = frequency*60;
  unsigned long curMillis = millis();  
  unsigned long curSeconds = curMillis/1000;   // Get current seconds
  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus
  Serial.print(" Requesting temperatures...");
  sensors.requestTemperatures(); // Send the command to get temperatures
  Serial.println("DONE");
  temperature1=sensors.getTempCByIndex(0);
  temperature2=sensors.getTempCByIndex(1);
  temperature3=sensors.getTempCByIndex(2);
  logData();

  lcd.setCursor(0, 0);
  lcd.print("T1=");
  lcd.setCursor(3, 0);
  lcd.print(temperature1);
  lcd.setCursor(8, 0);
  lcd.print("T2=");
  lcd.setCursor(11, 0);
  lcd.print(temperature2);
  lcd.setCursor(0, 1);
  lcd.print("T3=");
  lcd.setCursor(3, 1);
  lcd.print(temperature3);
  lcd.setCursor(8, 1);
  lcd.print("S=");
  lcd.setCursor(10, 1);
  lcd.print(curSeconds);
    // You can have more than one IC on the same bus. 
    // 0 refers to the first IC on the wire

}

double sum=0.0;
int count=0;

void logData() {
  unsigned long curMillis = millis();          // Get current time
  unsigned long curSeconds = curMillis/1000;   // Get current seconds
  Serial.print("Time="); Serial.print(curSeconds);
  Serial.print(" Temperature1 = "); Serial.print(temperature1);
  Serial.print(" Temperature2 = "); Serial.print(temperature2);
  Serial.print(" Temperature3 = "); Serial.print(temperature3);
  Serial.print(" RPM = "); Serial.println(RPM);
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File myFile = SD.open("LOG.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to LOG.txt...");                        // Printing to serial communication
    myFile.print("Time = "); myFile.print(curSeconds);            // Printing to log file on sd card
    myFile.print(" Temperature1 = "); myFile.print(temperature1);   // Printing to log file on sd card
    myFile.print(" Temperature2 = "); myFile.print(temperature2);         // Printing to log file on sd card
    myFile.print(" Temperature3 = "); myFile.print(temperature3);       // Printing to log file on sd card
    myFile.print(" RPM = "); myFile.println(RPM);       // Printing to log file on sd card
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening LOG.txt");                      // Error either SD card not connected or not detected
  }
  delay(100);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.