0

I have a problem of synchronization between data sent from LabView interface to Arduino. This is my code. I am using a SHT31 sensor to send temperature and humidity from Arduino to LabView after receiving a character specified. This part doesn't work correctly. I am using also a heating resistors activated by a random number in the LabView interface

Can anyone help me in putting interrupts in every event?

#include <Arduino.h>
#include <Wire.h>
#include <TimerOne.h>
#include "Adafruit_SHT31.h"

Adafruit_SHT31 sht31 = Adafruit_SHT31();
int etat=0,indicT=0,indicS=0;
String caract,stringVal1,stringVal2,stringVal3,stringVal4,s;
int T,randNumber;

void setup()
{
  // capteur
  while (!Serial)
  delay(10);  // will pause Zero, Leonardo, etc until serial console opens
  if (!sht31.begin(0x44))
  {   // Set to 0x45 for alternate i2c addr
    while (1) delay(1);
  }

  //rand
  randNumber = random(1,4);
  // put your setup code here, to run once:
  pinMode(40,OUTPUT);
  pinMode(41,OUTPUT);
  pinMode(22,OUTPUT);
  pinMode(24,OUTPUT);
  pinMode(26,OUTPUT);
  pinMode(28,OUTPUT);
  pinMode(30,OUTPUT);
  pinMode(32,OUTPUT);
  pinMode(31,OUTPUT);
  pinMode(33,OUTPUT);
  pinMode(13,OUTPUT);
  noInterrupts(); // désactiver toutes les interruptions
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = 15625; // 16MHz/256/2Hz
  TCCR1B |= (1 << WGM12); // CTC mode
  TCCR1B |= (1 << CS12); // 256 prescaler
  TIMSK1 |= (1 << OCIE1A); // Activer le mode de comparaison
  interrupts(); // activer toutes les interruptions

  Serial.begin(115200);
}

ISR(TIMER1_COMPA_vect) // fonction périodique
{
  caract = (char)Serial.read();
}

void serialEvent()
{
  while (Serial.available())
  {
    caract = (char)Serial.read();
    indicS=!indicS;
  }
}

void moteur(int s)
{
  if(s)
  {
    digitalWrite(40,1);
    digitalWrite(41,0);
  }
  else
  {
    digitalWrite(40,0);
    digitalWrite(41,1);
  }
}

void initialisation()
{
  digitalWrite(22,LOW);
  digitalWrite(26,LOW);
  digitalWrite(24,LOW);
  digitalWrite(30,LOW);
  digitalWrite(28,LOW);
  digitalWrite(32,LOW);
  digitalWrite(40,LOW);
  digitalWrite(41,LOW);
}

long getDecimal(float val)
{
  int intPart = int(val);

  //I am multiplying by 1000 assuming that the foat values will have a
  //maximum of 3 decimal places.
  //Change to match the number of decimal places you need
  long decPart = 1000*(val-intPart);
  if(decPart>0)return(decPart);           //return the decimal part of
                                          //float number if it is available
  else if(decPart<0)return((-1)*decPart); //if negative, multiply by -1
  else if(decPart=0)return(00);           //return 0 if decimal part of
                                          //float number is not available
}

void loop()
{
  // consigne
  interrupts(); // activer toutes les interruptions

  if(caract=="P")
  {
    //    Serial.print("connect");
    //relais ouvert
    digitalWrite(40,0);
    digitalWrite(41,1);
    indicS=0;

    //résistance aléatoire
    Serial.print(randNumber);
    switch(randNumber)
    {
      case 1:
        {
          digitalWrite(22,HIGH);
          digitalWrite(26,HIGH);
          // Serial.print('A');
        }
        break;
      case 2 :
        {
          digitalWrite(24,HIGH);
          digitalWrite(30,HIGH);
          // Serial.print('B');
        }
        break;
      case 3 :
        {
          digitalWrite(28,HIGH);
          digitalWrite(32,HIGH);
          // Serial.print('D');
        }
        break;
    }

    //temperature et humidité  d'entrée
    float t1 = sht31.readTemperature();
    stringVal1+=String(int(t1))+ "."+String(getDecimal(t1));
    //Serial.println(stringVal1);
    float h1 = sht31.readHumidity();
    stringVal2+=String(int(h1))+ "."+String(getDecimal(h1));
    // Serial.println(stringVal2);

    if(caract=="TE")
    {
      Serial.println(stringVal1);
    }
    if(caract=="HU")
    {
      Serial.println(stringVal2);
    }
  }

  //  if(indicS){
  // Serial.print(caract);
  // indicS=0;
  //  }
  //exemple led 13 interreption
  //if(indicT)
  //{
  //  digitalWrite(13,etat);
  //  etat=!etat;
  //  indicT=0;
  //}
}

closed as unclear what you're asking by Code Gorilla, gre_gor, jfpoilpret, Greenonline, Enric Blanco Jun 28 '17 at 10:23

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    We need more details. Describe exactly what isn't working and what you want to achieve with interrupts. – TisteAndii Jun 26 '17 at 20:54
2

I tried to make sense of your code, but I didn't quite understand everything, for two reasons:

  • your question is not very clear, as you don't completely specify what you want your program to do

  • the code itself is not always clear about what it's doing: some variable should have better names and some more comments are needed to make things clear.

These are also the most likely reasons you got a closing vote.

Despite this limited understanding, I tried to clean up the program. Here are the improvements I suggest:

  1. The first thing to do is get rid of the timer. You are trying to read the serial port both from a timer event and from serialEvent(), which makes little sense. You should also remove all unused functions, variables and #includes, they only make your program harder to read.

  2. Your getDecimal() function is a very misguided attempt to format a number. If you call getDecimal(23.008) you get 8 (or maybe 7, depending on rounding), and you print it as 23.8. The simplest way to get what you want is to let Serial.println() do the formatting. You can pass a second argument to specify how many decimal places you want.

  3. There is a bug in your usage of stringVal1 and stringVal2: you are always adding data to them, which will inevitably exhaust your available memory.

  4. You always store a single character in your caract string, therefore this string can never be "HU". The easiest fix is to use single-character commands (e.g. “H” for humidity), then you don't need a String and you remove the risk of running into memory issues.

  5. You should process input characters only as you read them. Reading them in serialEvent() and processing them in loop() will get you out of sync, so do both in the same function.

  6. Note that Serial.read() returns an int, which is -1 if there is no data available. Thus, if you are going to compare to specific values, you don't need to test for Serial.available().

  7. If you set your heater index to a random number between 0 and 2, then you can use it as an index into an array of pins.

And here is a version of your program implementing all of the above:

#include "Adafruit_SHT31.h"

// Heating resistors.
const int HEATER_PINS[3][2] = {{22, 26}, {24, 30}, {28, 32}};

// Other used pins... but what for?
const int EXTRA_PINS[] = {40, 41, 31, 33, 13};
const int EXTRA_PINS_COUNT = sizeof EXTRA_PINS / sizeof EXTRA_PINS[0];

int heater;  // randomly selected heater
Adafruit_SHT31 sht31 = Adafruit_SHT31();

void setup()
{
    while (!Serial)
        ;  // will pause Zero, Leonardo, etc until serial console opens
    Serial.begin(115200);

    if (!sht31.begin(0x44)) {  // set to 0x45 for alternate i2c addr
        exit(1);  // abort
    }

    // Randomly choose a heater.
    heater = random(0, 3);

    for (int i = 0; i < 3; i++) {
        pinMode(HEATER_PINS[i][0], OUTPUT);
        pinMode(HEATER_PINS[i][1], OUTPUT);
    }
    for (int i = 0; i < EXTRA_PINS_COUNT; i++) {
        pinMode(EXTRA_PINS[i], OUTPUT);
    }
}

void loop()
{
    switch (Serial.read()) {
        case 'P':
            // Open relay.
            digitalWrite(40, 0);
            digitalWrite(41, 1);

            // Turn on heater.
            Serial.print(heater + 1);
            digitalWrite(HEATER_PINS[heater][0], HIGH);
            digitalWrite(HEATER_PINS[heater][1], HIGH);
            break;
        case 'T':
            Serial.println(sht31.readTemperature(), 3);
            break;
        case 'H':
            Serial.println(sht31.readHumidity(), 3);
            break;
    }
}

Note that EXTRA_PINS is a very poorly named constant. You should find better constant names, but I couldn't figure out what you wanted to do with those pins.

  • my program is based on operation of a dryer used in biology to measure the dry plant so its operation is as follows first we put the temperature in the drying operation then an air flow is launch to activate two among six of the heaters when we want to weighing the relay plug going to be close and two SHT31 sensors will give us temperatures and humidities of entry and exit... This whole process is done by a program arduino and labview will be its interfacela communication between the two is made by sending and reception of the alphabet to know the step to do – mariemLAOUEJ Jun 27 '17 at 20:51
  • that's why i think about using interreption because i didn't find a synchronization with labview always arduino read and send just one data – mariemLAOUEJ Jun 27 '17 at 20:54
  • and about waiting for the caracter P it is a protocol of communication wich is done when i press a bouton connect in the interface. Hope i explain my object to you . – mariemLAOUEJ Jun 27 '17 at 20:57
  • Maybe you could try to describe all that in an edit to your original question. Also, describe if possible the communication protocol, and tell us whether it's possible to change it. – Edgar Bonet Jun 27 '17 at 20:59
  • i used the protocole of communication just in way to say im ready to start i can not change it my problem how to make arduino read many serial data ,, is that by using switch case !! – mariemLAOUEJ Jun 27 '17 at 21:13

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