Go Down

Topic: Interrupts cli() & sei() (Read 20844 times) previous topic - next topic


Have seen a few sketches use cli() and sei().

How do they differ from noInterrupts() & interrupts(), and are they interchangeable.


Coding Badly

Interchangeable.  The latter is presumably more portable in case you're considering the Due.

Tom Carpenter

They are the same:

Courtesy of Arduino.h:
Code: [Select]

#define interrupts() sei()
#define noInterrupts() cli()


Fantastic, tks for the info (heck had to wait nearly 5 minutes for the answer, you will just have to do better next time).


Good afternoon, I'm programming with the Arduino UNO and an Ethernet Shilds, which sends data to a server (thingspeak.com). It works fine, but when I insert the function sei () and cli (), the connection is paralyzed. I use this function to read a Hall effect flow sensor. How to solve this and not lose the accuracy of flow measurement. Thank you.


 Reads analog voltages from pins 0-7 and writes them to the 8 fields of a channel on ThingSpeak every 20 seconds.

 ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize and
 analyze live data streams in the cloud.

 Copyright 2017, The MathWorks, Inc.

 Documentation for the ThingSpeak Communication Library for Arduino is in the extras/documentation folder where the library was installed.
 See the accompaning licence file for licensing information.

#include "ThingSpeak.h"

// ***********************************************************************************************************
// This example selects the correct library to use based on the board selected under the Tools menu in the IDE.
// Yun, Ethernet shield, WiFi101 shield, esp8266, and MXR1000 are all supported.
// With Yun, the default is that you're using the Ethernet connection.
// If you're using a wi-fi 101 or ethernet shield (http://www.arduino.cc/en/Main/ArduinoWiFiShield), uncomment the corresponding line below
// ***********************************************************************************************************

//#define USE_WIFI101_SHIELD

#if !defined(USE_WIFI101_SHIELD) && !defined(USE_ETHERNET_SHIELD) && !defined(ARDUINO_SAMD_MKR1000) && !defined(ARDUINO_AVR_YUN) && !defined(ARDUINO_ARCH_ESP8266)
#error "Uncomment the #define for either USE_WIFI101_SHIELD or USE_ETHERNET_SHIELD"

#if defined(ARDUINO_AVR_YUN)
#include "YunClient.h"
YunClient client;
#if defined(USE_WIFI101_SHIELD) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_ARCH_ESP8266)
// Use WiFi
#include <ESP8266WiFi.h>
#include <SPI.h>
#include <WiFi101.h>
char ssid[] = "<BLACKOPS 2.4 Ghz>";    //  your network SSID (name)
char pass[] = "<wellcome>";   // your network password
int status = WL_IDLE_STATUS;
WiFiClient  client;
#elif defined(USE_ETHERNET_SHIELD)
// Use wired ethernet shield
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
EthernetClient client;

 **** Visit https://www.thingspeak.com to sign up for a free account and create
 **** a channel.  The video tutorial http://community.thingspeak.com/tutorials/thingspeak-channels/
 **** has more information. You need to change this to your channel, and your write API key
#include <Ultrasonic.h>
Ultrasonic ultrasonic(8, 9);

// Inicializa variáveis do ultrason para medição do tanque
float MetCub = 0; // Metros cubicos do tanque, será calculado
float diaTq = 1.8; // Define o diâmetro do tanque em m // Comprimento da circunferencia externa do tanque = 5,64 m => r = Comprimento/2/3,14
float CompTq = 3.14 * (pow((diaTq / 2) , 2)); // Area da base, PI * R² - em metros²
float ProfTq = 108; // Profundidade total do tanque em m
float volini = 0; // Volume inicial do tanque
float volatu = 0; // Volume atual do tanque
float embasa = 0; // Volume cauculado de água recebido no tanque
int nivel = 0; // Inicializa variável do nível do tanque
int controle = 1; // Define quando liga o arduíno o volume inicial do tanque

// Inicializa variáveis do sensor de fluxo
float vazao; //Variável para armazenar o valor em L/min
float media = 0; //Variável para tirar a média a cada 1 minuto
int contaPulso; //Variável para a quantidade de pulsos
int i = 0; //Variável para contagem

unsigned long myChannelNumber = 317777;
const char * myWriteAPIKey = "xxxxTP9BBxxxWQIV";

//unsigned long myChannelNumber = 318888;
//const char * myWriteAPIKey = "xxx7RFUVxxA9W";

void setup() {


 pinMode(18, INPUT);
 attachInterrupt(5, incpulso, RISING); //Configura o pino 2(Interrupção 0) para trabalhar como interrupção
 //Serial.println("\n\nInicio\n\n"); //Imprime Inicio na serial

#if defined(ARDUINO_ARCH_ESP8266) || defined(USE_WIFI101_SHIELD) || defined(ARDUINO_SAMD_MKR1000)
 WiFi.begin(ssid, pass);



void loop() {
 //******* Medidor de Vazão ************
 contaPulso = 0;   //Zera a variável para contar os giros por segundos
 sei();      //Habilita interrupção
 delay (1000); //Aguarda 1 segundo
 cli();      //Desabilita interrupção

 vazao = contaPulso / 5.5; //Converte para L/min
 media = media + vazao; //Soma a vazão para o calculo da media
 Serial.print(vazao); //Imprime na serial o valor da vazão
 Serial.print(" L/min - "); //Imprime L/min
 Serial.print(i); //Imprime a contagem i (segundos)
 Serial.println("s"); //Imprime s indicando que está em segundos

 if (i == 60)
   media = media / 60; //Tira a media dividindo por 60
//   Serial.print("\nMedia por minuto = "); //Imprime a frase Media por minuto =
//   Serial.print(media); //Imprime o valor da media
//   Serial.println(" L/min - "); //Imprime L/min
//   Serial.println("\n\nInicio\n\n"); //Imprime Inicio indicando que a contagem iniciou


 float cmMsec, inMsec;
 cmMsec = ultrasonic.distanceRead(); // Determina a distância entre o sensor ultrasônico e o nível de água
 nivel = (ProfTq) - cmMsec ; // Determina o nível de água do tanque em cm
 MetCub = CompTq * nivel * 10; // Caucula quantos litros de água tem o tanque

 // Armazena o valor do nível do tanque na variável, isso ocorre uma única vez quando roda o programa
 if (controle == 1) {
   volini = MetCub;
   controle = 0;

#ifndef ARDUINO_ARCH_ESP8266

 //Serial.print("Distance in CM: ");

 ThingSpeak.setField(1, String (nivel)); // Nível do tanque
 ThingSpeak.setField(2, String (media)); // Vazão do Bomba
 ThingSpeak.setField(3, String (random(0, 20))); // Vazão da EMBASA
 ThingSpeak.setField(4, String (random(0, 20000))); // Volume Bomba acumulado
 ThingSpeak.setField(5, String (random(0, 20000))); // Volume Embasa acumulada
 ThingSpeak.setField(6, String (MetCub)); // Volume do tanque
 ThingSpeak.setField(7, String (ultrasonic.distanceRead())); // Soma Bomba


 // Write the fields that you've set all at once.
 ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);

 delay(20000); // ThingSpeak will only accept updates every 15 seconds.
 media = 0; //Zera a variável media para uma nova contagem Vazão
 i = 0; //Zera a variável i para uma nova contagem Vazão

void incpulso ()
 contaPulso++; //Incrementa a variável de contagem dos pulsos


Please modify your post and use the code button </>
Code: [Select]
so your code looks like this and is easy to copy to a text editor. See How to use the Forum Your code is too long for me to study quickly without copying to a text editor.

It would also be a good idea to use the AutoFormat tool to indent your code for easier reading

Two or three hours spent thinking and reading documentation solves most programming problems.


Code: [Select]
void loop() {
 //******* Medidor de Vazão ************
 contaPulso = 0;   //Zera a variável para contar os giros por segundos
 sei();      //Habilita interrupção
 delay (1000); //Aguarda 1 segundo
 cli();      //Desabilita interrupção

This is the stupidest possible way to read interrupts from some device.

Leave interrupts on ALL the time. Get rid of the delay() call.

Once a second, or less often, if other stuff takes a long time, use millis() to see if it is time to make use of the number of pulses that the interrupt counted. If it is, only then should you disable interrupts, and then, only long enough to copy the count and then reset it.

Use the pulse count and the time during which the pulses occurred to determine pulses per second.
The art of getting good answers lies in asking good questions.

Go Up