Hello
ill have some question
about
nointerrupt and I2C wire bus.
my idea is some sensible code of my project save with Nointerrupt
// beginn sensible code
noInterrupts();
for(int i = 0; i < E_I2C2_MAX; i++)
{
help = digitalRead(i);
if(help == bitRead(signale_momentan[i/32],i%32))
{
bitWrite(signale_entprellt[i/32],(i%32),help);
}
bitWrite(signale_momentan[i/32],(i%32),help);
}
interrupts();
//end of sensible code
also ill use the
Wire.onRequest(requestEvent);
but the problem ist Nointerrupts(); and interrupts();
dont work for this.
when Wire.onRequest(requestEvent); starts he jump out of the sensible code and do the request event.
my question:
is there some idea that Wire.onRequest(requestEvent); didnt break the sensible code lines?
#include <Wire.h>
#include "c:\\temp\\signals.h"
//#define DEBUG
unsigned long signale_momentan[MAX_ANZAHL_SIGNALE_SPEICHER_UL]; //wahre groesse: 1+E_I2C2_MAX/8
unsigned long signale_entprellt[MAX_ANZAHL_SIGNALE_SPEICHER_UL];
void setup()
{
for(int i = 0; i < E_I2C2_MAX; i++)
{
pinMode(i, INPUT);
}
Wire.begin(I2C2); // join i2c bus with address #2
Wire.onRequest(requestEvent); // register event
#ifdef DEBUG
Serial.begin(9600); // start serial for output
#endif
for(int i = 0; i < E_I2C2_MAX; i++)
{
bitWrite(signale_entprellt[i/32],(i%32),i%2/*digitalRead(i)*/);
bitWrite(signale_momentan[i/32],(i/32),i%2/*digitalRead(i)*/);
}
}
void loop()
{
int help;
delay(20);
//noInterrupts();
for(int i = 0; i < E_I2C2_MAX; i++)
{
help = digitalRead(i);
if(help == bitRead(signale_momentan[i/32],i%32))
{
bitWrite(signale_entprellt[i/32],(i%32),help);
}
bitWrite(signale_momentan[i/32],(i%32),help);
}
//interrupts();
#ifdef DEBUG
Serial.println(signale_entprellt[0],BIN);
Serial.println(signale_entprellt[1],BIN);
Serial.println(sizeof(unsigned long));
delay(1000);
#endif
#ifdef DEBUG
signale_entprellt[0] = 0x12345678;
signale_entprellt[1] = 0x87654321;
#endif
}
// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent()
{
uint8_t* adress;
adress = (uint8_t*) signale_entprellt;
Wire.write(adress,sizeof(signale_entprellt));
}
when Wire.onRequest(requestEvent); starts he jump out of the sensible code and do the request event.
How do you know this?
ill tested it with delay function
between the no interupt tags
F.e
noInterrupts();
for(int i = 0; i < E_I2C2_MAX; i++)
{
help = digitalRead(i);
if(help == bitRead(signale_momentan[i/32],i%32))
{
bitWrite(signale_entprellt[i/32],(i%32),help);
}
bitWrite(signale_momentan[i/32],(i%32),help);
}
delay(5000);
interrupts();
if i am right the programcounter wait 5 sec between noInterrupts() and interrupts()
the request events start every 0.5 second.
so 5 seconds long the requestevent cant recive data.
but in tests , the master at IC2 bus get every 0,5 seconds data from the slave.
so my opinion is noInterrupts() and interrupts() did not work for Wire interrupts.
No, but there may be a special meaning. If you put an input to HIGH, you're activating the internal pull-up resistor for that pin. Usually you set the ports direction and then set the value it should have.
the delay5000 only was for testing
normaly there is no delay needed.
the problem is not clear for me.
when the programcounter is at the moment in the bitWrite section
for(int i = 0; i < E_I2C2_MAX; i++)
{
help = digitalRead(i);
if(help == bitRead(signale_momentan[i/32],i%32))
{
bitWrite(signale_entprellt[i/32],(i%32),help);
}
bitWrite(signale_momentan[i/32],(i%32),help);
}
and at same time there comes the interupt from wire request.
he would jump out and do the wire-request routine.
is there be a chance that some bits got lost when the programcounter go back into the bitwriteloop
so ill try out the
noInterrupts();
..
..
..
interrupts();
[code]
but wire request dont care of noInterupts ill think.
some ideas too this?
@ pylon
thanx for info
because mircochip pic controller need 1. set pin to low and 2. set as output.
It should work. Unless you turn interrupts on somewhere else. Once you turn interrupts off you won't receive the wire request.
However you may lose bits because the Wire library cannot respond while interrupts are off. I think the I2C interface has a one-byte buffer. So you cannot afford for interrupts to be off for long.
You might be better making a copy of the data (eg. with memcpy) and sending the copy. Turn interrupts off long enough to make the copy, keep that part as short as possible. Then turn interrupts on again and send the copy.