Spanish Manejo de Interrupciones en ESP8266

jwgf

Member
Hola a todos, quisiera saber como se manejan las interrupciones en B4R, en programación normal de Arduino defino un pin, el modo de interrupción y el nombre de la ISR a la cual se dirigirá, cuando, por ejemplo dicho pin valla de High a Low, pero no se como hacerlo en B4R, gracias desde ya, Jorge.
 

josejad

Expert
Licensed User
Longtime User
Hola:

No estoy seguro de a qué te refieres, pero a ver si he entendido bien:

B4X:
Sub Process_Globals
    ......
    Private d1pins As D1Pins
    'Declaras tu pin, por ejemplo de tnrada
    Private d1 Pin
     ......
End Sub

Private Sub AppStart
    Serial1.Initialize(9600)
    Log("AppStart")   
     .....  
    'Inicializas tu pin, y le añades un listener (supongo que es a lo que llamas interrupción)  
    d1.Initialize(d1pins.D1, d1.MODE_INPUT_PULLUP)
    d1.DigitalWrite(False)
    d1.AddListener("pinButton_StateChanged")
  End Sub

Sub pinButton_StateChanged (State As Boolean)
    Log("State: ", State)
    'aquí ya haces lo que quieras
End Sub

saludos,
 

jwgf

Member
Hola, José, como siempre el primero en ayudarme, bueno no se si es lo mismo, ,,,, me refiero a las clásicas interrupciones por hardware, que pueden tener varias fuentes por ejemplo el ingreso de un pulso positivo o negativo a un pin, el overloop de un timer, la terminación de una lectura desde el ADC, el cambio de estado de un comparador, etc, etc, dependiendo claro esta del micro. Cuando se define un servicio de interrupción ISR, en un micro por ejemplo para detectar el cambio de estado de un pin, se define el pin propiamente dicho, el nombre de la ISR, y el modo , por ejemplo rising, para indicar que se dispare con un flanco ascendente.
La forma en que la interrupción funciona es la siguiente, cuando se detecta el evento en el pin, del modo especificado, el micro termina con la sentencia que esta ejecutando y carga en un registro la dirección actual del program counter, luego se dirige al puntero de dirección que apunta al label colocado como nombre de ISR, ejecuta el código dentro del ISR, y hace el camino contrario para retornar a la próxima instrucción apuntada por el program counter, asi funciona una interrupción en cualquier micro, un Z80, un Pic, Un Arduino, un ESP9266, etc. pero no se como se implementa en B4A, te pego un trozo de código para leer un sensor PIR escrito en C de Arduino para ESp8266
B4X:
// Set GPIOs for LED and PIR Motion Sensor
const int led = 12;
const int motionSensor = 14;

// Timer: Auxiliary variables
unsigned long now = millis();
unsigned long lastTrigger = 0;
boolean startTimer = false;

// Checks if motion was detected, sets LED HIGH and starts a timer
ICACHE_RAM_ATTR void detectsMovement() {
  Serial.println("MOTION DETECTED!!!");
  digitalWrite(led, HIGH);
  startTimer = true;
  lastTrigger = millis();
}

void setup() {
  // Serial port for debugging purposes
  Serial.begin(115200);
 
  // PIR Motion Sensor mode INPUT_PULLUP
  pinMode(motionSensor, INPUT_PULLUP);
  // Set motionSensor pin as interrupt, assign interrupt function and set RISING mode
  attachInterrupt(digitalPinToInterrupt(motionSensor), detectsMovement, RISING);

  // Set LED to LOW
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
}

void loop() {
  // Current time
  now = millis();
  // Turn off the LED after the number of seconds defined in the timeSeconds variable
  if(startTimer && (now - lastTrigger > (timeSeconds*1000))) {
    Serial.println("Motion stopped...");
    digitalWrite(led, LOW);
    startTimer = false;
  }
}

Un abrazo y espero tu ayuda, Jorge
 

josejad

Expert
Licensed User
Longtime User

jwgf

Member
Hola José, gracias por contestar, bueno he estado probando y efectivamente las interrupciones ( por lo menos a las referidas a un pin ) , se manejan con AddListener, no tengo idea de como hacerlo para otras fuentes de interrupción. Por otro lado he estado realizando algunas mediciones que pueden ser de utilidad para algún otro ingeniero que desarrolle con B4R, genere un pulso cuadrado de 1 mS que saque por el pin 5 de un NodeMCU 8266, y declare una entrada con
AddListener en el pin 4 y la uní, ademas agregue un pin 14 como salida para poder minitorear los estados, conecte un osciloscopio a ambas salidas y pude "ver" el tiempo que demora en detectar la interrupción o generar el evento, bueno es muy rápido , 2,6 uS con el micro trabajando en forma normal 80 Mhz, la misma prueba en un Arduino Uno me dio 13,4 uS. Pego el código que use para la prueba, un dato muy interesante es que la interrupción se "adelanta" a la salida, estimo que esto sucede porque en los registros internos de los puertos sobre el buffer de salida se produce el cambio y este genera la interrupción, luego se produce la escritura del puerto en el pin de salida. Un abrazo y quedo atento a cualquier inquietud, Jorge Garcia.
B4X:
Sub Process_Globals
    Public Serial1 As Serial
    Private ip, op, salp As Pin
    Dim Set = False As Boolean

End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
    
    ip.Initialize (4, ip.MODE_INPUT)
    op.Initialize (5, op.MODE_OUTPUT)
    salp.Initialize (14, salp.MODE_OUTPUT)
    op.DigitalWrite(False)
    salp.DigitalWrite(False)
    ip.AddListener("Change_state")
    AddLooper("Looper")
    
End Sub

Sub Looper
    If op.DigitalRead Then
        op.DigitalWrite(False)
    Else
        op.DigitalWrite(True)
    End If
    Delay(1)
End Sub
 
Sub Change_state (State As Boolean)
    Set = Not(Set)
    If Set Then
        salp.DigitalWrite(True)
    Else
        salp.DigitalWrite(False)
    End If

End Sub
 
Top