Giter Site home page Giter Site logo

softwire's People

Contributors

bxparks avatar matthijskooijman avatar stevemarple avatar waynepiekarski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

softwire's Issues

Problem with handling of timeout

I have implemented a I2C master on a STM32F103 and it works correctly.
However, while performing tests, I did an experiment: I shorted the scl line to ground, to see whether this was correctly handled. My application then crashed. After a long examination, I found that in such a case there is an infinite indirect recursion, thus the crash.
The problem lies in the function sclHighAndStretch. In case of a timeout, it calls the function stop which itself calls sclHighAndStretch . We need a way to break this recursion. I see two ways:

  • add an extra parameter to sclHighAndStretch to hold it from calling stop again.
    or
  • write a special stop2 code for this instance, that does not call sclHighAndStretch again.

PS : advice : in the description of the library, it would be useful to specify that the user needs to supply a read and a write buffer at initialisation time. I had a hard time figuring out what was wrong until I discovered this. I used to use a library from Roger Clark's package that was very close, but that did not require buffers to be supplied, so I was not aware of the need of buffers.

Not available on rp2040 (raspberry pie Pico).

Problem:
I use mpu6050 sensor and raspberry pie Pico development board. I can make sure the wiring is correct. However, the same code can run on Arduino uno and esp32, and can correctly read mpu6050 data. After the raspberry pie Pico runs, it cannot correctly read data.(Raspberry pie enables Pico to read normally using hardware IIC.)

arduino for rp2040:
https://github.com/earlephilhower/arduino-pico

Picture:
image
Raspberry pie Pico failed to read with software IIC:
image
Arduino uno successfully read with software IIC:
image

Code:

#include <SoftWire.h>
SoftWire Wire(12, 13); // Raspberry pie Pico(SDA=12,SCL=13) ,ARDUINO UNO(SDA=2,SCL=3)

const int MPU6050_addr = 0x68;
int16_t AccX, AccY, AccZ, Temp, GyroX, GyroY, GyroZ;
uint8_t swTxBuffer[32];
uint8_t swRxBuffer[32];

void setup() {
Wire.setTxBuffer(swTxBuffer, sizeof(swTxBuffer));
Wire.setRxBuffer(swRxBuffer, sizeof(swRxBuffer));
Wire.begin();
Wire.beginTransmission(MPU6050_addr);
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);
Serial.begin(9600);
}

void loop() {
Wire.beginTransmission(MPU6050_addr);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU6050_addr, 14, true);
AccX = Wire.read() << 8 | Wire.read();
AccY = Wire.read() << 8 | Wire.read();
AccZ = Wire.read() << 8 | Wire.read();
Temp = Wire.read() << 8 | Wire.read();
GyroX = Wire.read() << 8 | Wire.read();
GyroY = Wire.read() << 8 | Wire.read();
GyroZ = Wire.read() << 8 | Wire.read();

Serial.print("AccX = ");
Serial.print(AccX);
Serial.print(" || AccY = ");
Serial.print(AccY);
Serial.print(" || AccZ = ");
Serial.print(AccZ);
Serial.print(" || GyroX = ");
Serial.print(GyroX);
Serial.print(" || GyroY = ");
Serial.print(GyroY);
Serial.print(" || GyroZ = ");
Serial.print(GyroZ);
Serial.print(" || Temp = ");
Serial.println(Temp / 340.00 + 36.53);
delay(500);
}

Softwire and Heltec OLED

Hi,

I'm tring to use SoftWire to connect to BME280 on a heltec wifi kit32.
If I use soft SDA SCL (GPIO_4,GPIO_15) respectivley it works fine. (note the I2C OLED diplay is connected to 4,15
When I move the BME280 to two other GPIO's (21,21) it work fine until i call the SDD1306 lib display.init() command.
This appaers to set the SoftWire pins back to (4,15)
Does this mean I cant use SDD1306 and SoftWire on differnet pins?

Nice library btw ..
Thanks

SoftWire and AS7262/3 library

Awesome work on the SoftWire library.

The AS7262 and AS7263 sensors both have the same address making it a little awkward to add both in to the one project. They both use the Wire library and I was hoping to be able to use the SoftWire library instead however not sure how to set it up for this.

In the AS726X library they use the wire lib in the flowing way. I have truncated the bits that are not related to the I2C.

Do you think there is any way to replace the way the code uses Wire with SoftWire?

[AS7261.cpp]
`#include "AS7261.h"
#include "Arduino.h"
//Sets up the sensor for constant read
//Returns the sensor version (AS7262 or AS7263)
AS726X::AS726X()
{
}
void AS726X::begin(TwoWire &wirePort, byte gain, byte measurementMode)
{
_i2cPort = &wirePort;
_i2cPort->begin();
Serial.begin(115200);
}
//Does a soft reset
//Give sensor at least 1000ms to reset
void AS726X::softReset()
{
//Read, mask/set, write
byte value = virtualReadRegister(AS726x_CONTROL_SETUP); //Read
value |= (1 << 7); //Set RST bit
virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
}

//Read a virtual register from the AS726x
byte AS726X::virtualReadRegister(byte virtualAddr)
{
byte status;

//Do a prelim check of the read register
status = readRegister(AS72XX_SLAVE_STATUS_REG);
if ((status & AS72XX_SLAVE_RX_VALID) != 0) //There is data to be read
{
//Serial.println("Premptive read");
byte incoming = readRegister(AS72XX_SLAVE_READ_REG); //Read the byte but do nothing with it
}

//Wait for WRITE flag to clear
while (1)
{
status = readRegister(AS72XX_SLAVE_STATUS_REG);
if ((status & AS72XX_SLAVE_TX_VALID) == 0) break; // If TX bit is clear, it is ok to write
delay(POLLING_DELAY);
}

// Send the virtual register address (bit 7 should be 0 to indicate we are reading a register).
writeRegister(AS72XX_SLAVE_WRITE_REG, virtualAddr);

//Wait for READ flag to be set
while (1)
{
status = readRegister(AS72XX_SLAVE_STATUS_REG);
if ((status & AS72XX_SLAVE_RX_VALID) != 0) break; // Read data is ready.
delay(POLLING_DELAY);
}

byte incoming = readRegister(AS72XX_SLAVE_READ_REG);
return (incoming);
}

//Write to a virtual register in the AS726x
void AS726X::virtualWriteRegister(byte virtualAddr, byte dataToWrite)
{
byte status;

//Wait for WRITE register to be empty
while (1)
{
status = readRegister(AS72XX_SLAVE_STATUS_REG);
if ((status & AS72XX_SLAVE_TX_VALID) == 0) break; // No inbound TX pending at slave. Okay to write now.
delay(POLLING_DELAY);
}

// Send the virtual register address (setting bit 7 to indicate we are writing to a register).
writeRegister(AS72XX_SLAVE_WRITE_REG, (virtualAddr | 0x80));

//Wait for WRITE register to be empty
while (1)
{
status = readRegister(AS72XX_SLAVE_STATUS_REG);
if ((status & AS72XX_SLAVE_TX_VALID) == 0) break; // No inbound TX pending at slave. Okay to write now.
delay(POLLING_DELAY);
}

// Send the data to complete the operation.
writeRegister(AS72XX_SLAVE_WRITE_REG, dataToWrite);
}

//Reads from a give location from the AS726x
byte AS726X::readRegister(byte addr)
{
_i2cPort->beginTransmission(AS726X_ADDR);
_i2cPort->write(addr);
_i2cPort->endTransmission();

_i2cPort->requestFrom(AS726X_ADDR, 1);
if (_i2cPort->available()) {
return (_i2cPort->read());
}
else {
Serial.println("I2C Error");
return (0xFF); //Error
}
}

//Write a value to a spot in the AS726x
void AS726X::writeRegister(byte addr, byte val)
{
_i2cPort->beginTransmission(AS726X_ADDR);
_i2cPort->write(addr);
_i2cPort->write(val);
_i2cPort->endTransmission();
}
`

[AS7261.h]
#ifndef _AS7261_h #define _AS7261_h #include "Arduino.h" #include "Wire.h" class AS726X { public: AS726X(); void begin(TwoWire &wirePort = Wire, byte gain = 3, byte measurementMode = 3); private: TwoWire *_i2cPort; };

example SoftWire_MLX90614 not working

Hi Steve,
I'm using a MLX90614 connected to ESP32-C3 super micro board with Arduino-IDE 2.3.2. So I tried your example "SoftWire_MLX90614", but no success. I found following problems in your example :

  1. there is no pause after Serial.begin() and so the following Serial.println("MLX90614_demo") is not done. (small problem ;-))
  2. at the function "readMLX90614(uint8_t command, uint8_t &crc)" you use "i2c.write(command);". But that does't send the command-byte on I2C-bus. I replaced it with "i2c.llWrite(command);" That works.
  3. in loop() the "readMLX90614()" is called twice to get Ambient- and Object-temperature. That leads to hang-up of the program. If I insert a little pause (for ex. : delay(1)) between the two "readMLX90614()", the program runs and both values are read fine.

While I had the problems above, I saw that you created a library for the MLX90614. So I installed it and tried example MLX90614_demo. But I got compilation error :
".....src\ MLX90614.cpp: In member function 'bool MLX90614::read(uint8_t, uint16_t&) const':
d:\Program Files (x86)\Arduino\neue_Libraries\libraries\MLX90614\src\MLX90614.cpp:154:24: error: passing 'const SoftWire' as 'this' argument discards qualifiers [-fpermissive]
i2c.write(command) || // Command sent"
I didn't check further for that because I'm using SoftWire with the problem solutions above.

I hope my comments can help others with the same problems.
Thank you Steve for SoftWire, it runs really fine in my project now.

configure SoftWire and set up buffer

Hi stevemarple,
i want to use softWire for 3 pressure sensors with same address (because i dont have multiplexer) so i try to use ur library.
As u said high-level functions provide almost direct compatibility with the Wire library.
I dont know how to set up buffer, con figure SoftWire to use beginTransmission(), endTransmission(), read(), write() and requestFrom () and other high-level functions.
this is my code
softwire.txt

could you help me to it. Thank you so much

stm32duino support

I'm trying to use this SoftWire with stm32duino link. The library compiles fine and the example ListDevices.ino is working. However, the read() function seems to be broken on stm32 as it returns incorrect values. Any ideas how to get this library to work with stm32duino?

calling setClock(0) made arduino micro unrecognizable by windows

I don't have the source code anymore sadly, and I am kind of scared to repreduce the results on another board.
The code was very simple, though. It was something like that:

#include "SoftWire.h"

SoftWire Wire2(4, 5);

void setup()
{
    Wire2.begin();
    Wire2.setClock(0);
}

void loop()
{}

I'm not sure if I called setClock(0) before or after the begin() call.

I'm pretty sure that's what broke it because the parameter 0 in the setClock(0) function is the only value I changed before and after compiling and uploading.

If it's not only my hardware that's at risk, maybe it would be a good idea to prevent users from setting the clock to 0Hz, or to negative numbers (assuming that's even possible).

Better documentation of run-time setting sda and scl pins

Hello! Love your library Steve,
I was having trouble finding how to set sda pins and scl pins during runtime, I'm requesting this block of code be mentioned in the README:

void SoftWire::setSda(uint8_t sda)
{
	_sda = sda;
}


void SoftWire::setScl(uint8_t scl)
{
	_scl = scl;
}

softwire i2c for liquid crystal lcd

Hi
Couple of question if I may. 1.Is there any tested working softwire or softi2c lib for esp32 to control 16x2 liquid crystal lcd?
2.If it runs , will the original two i2c channels still work with other devices? (i already using twowire library to control 2 sensors, and normal i2c to control another 2sensors. I don't want any signal to mingle with the lcd so I look for alternative).
Thanks for any attention. Rich J.

Minimum SCL frequency

Hello,

¿Why does the library have a lower bound to the I2C frequency? It seems that the lowest frequency allowed by setClock is 1961 Hz. ¿Whats the reasoning behind this?

Nice library btw.

Does not implement TwoWire

Hello.
The class cannot be used as software I2C by other libraries, like Adafruit's because it does not implement the TwoWire interface.
Please add it, as your class already implements the needed methods.

Thanks!

PCF8583 event counter not woking with SoftWire

I am trying to use pfc8583 . Board is STM32. It always hangs on setMode function..

Sample code:

uint16_t PCF8583::setMode(uint8_t address,uint8_t mode)

{

_address = address >> 1;

// _wire = theWire;

if(!Newwire.available())

{

  Newwire.setTxBuffer(NewwireTxBuffer, sizeof(NewwireTxBuffer));

Newwire.setRxBuffer(NewwireRxBuffer, sizeof(NewwireRxBuffer));

Newwire.setTimeout(1000);

delay(100);

  Newwire.begin();

  delay(200);

}

// if(!Newwire.available())

// return 1;

// return 2;

delay(200);

// convert to 7 bit so Wire doesn't choke

uint8_t control = getRegister(LOCATION_CONTROL);

// uint8_t control = getRegister(LOCATION_CONTROL);

control = (control & ~MODE_TEST) | (mode & MODE_TEST);

setRegister(LOCATION_CONTROL, control);

}

It hangs when Calling setMode

Adafruit_MLX90614 and MAX30102 Not working

Hello Sir, thank you for sharing such excellent work.

I tried to use ESP32 wroom dev board and use Adafruit_MLX90614 and MAX30102 sensor on I2C communication. As you might know both works on I2C communication. but It did not work. Any piece of advice will be highly appreciated.

llStartWait() case nack needs to include break or return

In the llStartWait() function, the stop() call for case nack should include either a break; or a return immediately after it.
Currently my compiler is giving "warning: this statement may fall through".
It looks like it currently will call stop() twice, then return timedOut, but not sure what the actual intent is here.

SoftWire::result_t SoftWire::llStartWait(uint8_t rawAddr) const
{
        AsyncDelay timeout(_timeout_ms, AsyncDelay::MILLIS);

        while (!timeout.isExpired()) {
                // Force SDA low                                                                                                                                                                                  
                _sdaLow(this);
                delayMicroseconds(_delay_us);

                switch (llWrite(rawAddr)) {
                case ack:
                        return ack;
                case nack:
                        stop();
                default:
                        // timeout, and anything else we don't know about                                                                                                                                         
                        stop();
                        return timedOut;
                }
        }
        return timedOut;
}

I2C EEPROM example not working correctly (Wire functions used)

Wire.read() always returns 255
With Wire library example works correctly

`#include <SoftWire.h>
#include <AsyncDelay.h>

SoftWire Wire(SDA, SCL);

#define disk1 0x50 //Address of 24C32 eeprom chip

void setup(void)
{
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println("Wire");
Wire.begin();

unsigned int address = 0;
Serial.println("writeEEPROM");
writeEEPROM(disk1, address, 123);
Serial.println("readEEPROM");
Serial.println(readEEPROM(disk1, address), DEC);
Serial.println("end");
}

void loop(){}

void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data )
{
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.write(data);
Wire.endTransmission();

delay(5);
}

byte readEEPROM(int deviceaddress, unsigned int eeaddress )
{
byte rdata = 0xFF;

Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();

Wire.requestFrom(deviceaddress,1);

if (Wire.available()) rdata = Wire.read();

return rdata;
}`

Can't compile the SoftWire_MLX90614 example

Hi
this:

void exitPWM(void)
{
	// Make SMBus request to force SMBus output instead of PWM
	SoftWire::setSclLow(&i2c);
	delay(3); // Must be > 1.44ms
	SoftWire::setSclHigh(&i2c);
	delay(2);
}

should be:

void exitPWM(void)
{
	// Make SMBus request to force SMBus output instead of PWM
	SoftWire::sclLow(&i2c);
	delay(3); // Must be > 1.44ms
	SoftWire::sclHigh(&i2c);
	delay(2);
}

AS3935 library vs SoftWire question

Recompiled a slightly-modified, but working, program which used AS3935 and SoftWire to speak to an AS3935 in a MOD-1016 card. Wouldn't work. Backed out of changes. Still won't work. Tried demo. Wouldn't work. Hardware not changed.
Signal analyzer sees writes to 0x06 (AS3935 address is 0x03, so this is right) and 0x07, reads 0x24 always. It looks like SoftWire llwrite function buffers bytes to be sent, but nobody seems to call endTransmissionInner, which looks like it would be the thing to actually transmit what's in the buffer!
Here's the sequence I see:
SW: llWrite: 0x6
SW: llWrite: 0x6
SW: llWrite: 0x6
sPU=>sI1
SW: llWrite: 0x6
SW: llWrite: 0x6
SW: llWrite: 0x7
SW: llRead: got 0x24
SW: llWrite: 0x6
sI1=>sI2
SW: llWrite: 0x6
SW: llWrite: 0x7
SW: llRead: got 0x24
SW: llWrite: 0x6
SW: llWrite: 0x6
SW: llWrite: 0x7
SW: llRead: got 0x24
sI2=>sL
SW: llWrite: 0x6
SW: llWrite: 0x7
SW: llRead: got 0x24
SW: llWrite: 0x6
SW: llWrite: 0x6
SW: llWrite: 0x7
SW: llRead: got 0x24
Problem - noise floor was set to 0 but didn't set ==> 2

Did this get broken with the update to SoftWire? Or am I missing something else?

Here's my Arduino code:

#define PROGNAME "MOD-1016_AS3935_lightning_sensor.ino"
#define VERSION "0.3.4"
#define VERDATE "2018-08-04"

/*
Side notes: that program uses SoftWire, which initializes pin 14 (A0) for SDA
and pin 17 (A3) for SCL.

Many "Something else happened!" events

Two kinds of calls - process and getTriggered. What events lead to each?
getTriggered returns the value of _triggered
process turns _triggered off if state is WaitR
Does calling getInterruptFlags and getState clear these? No.
When should they be called?
Add a real-time clock to this setup, then hard-wire it; move it to an ESP so can
query a timeserver?

v0.3.0 removed dumping registers unless VERBOSE or actual lightning detected

*/

#include <AsyncDelay.h>
#include <SoftWire.h>
#include <AS3935.h>

#ifdef JTD
#include <DisableJTAG.h>
#endif

//************************
//************************

#define VERBOSE 4

const unsigned long BAUDRATE = 115200;
const int tabColumn = 40;

//************************
//************************

/*************************** hardware incl GPIO *******************************/

/*
connections:
A0 SDA for sensor (yellow)
A3 SCL for sensor (white)

	D2  IRQ line from sensor (blue)
	D13 LED

*/

const int piSensor = 2; // IRQ pin from sensor
const int intSensor = 0; // Arduino pin 2 is INT0; pin 3 (not used here) is INT1
const int pdThrobber = 13;

const uint8_t i2cAddr = 0x03;
const byte antennaTuningValue = 0x02;

/******************************* Global Vars **********************************/

int distanceEstimate = 0;
uint8_t count = 0;
bool ledState = true;

AS3935 as3935;

AsyncDelay throbberTimeout, textThrobberTimeout;

char states [ ] [ 6 ] = { "Off", "PwrUp", "Init1", "Init2", "Listn", "WaitR", "Cal" };

/************************** Function Prototypes *******************************/

void ISR_lightning_sensor (void);
void displayRegs ();

/******************************************************************************/

void setup () {

const int dly = 5;

#ifdef JTD
disableJTAG();
#endif

Serial.begin ( BAUDRATE );
while ( !Serial && millis() < 2000 );

// sda, scl, address, tunCap, indoor, timestamp
as3935.initialise ( 14, 17, i2cAddr, antennaTuningValue, true, NULL );
// no delays necessary - internal to as3935 code
// delay ( dly );

// as3935.reset();
// delay ( dly );
// as3935.clearStats();
// delay ( dly );

as3935.start();
// start implicitly calls calibrate
// delay ( dly );

// wait until it's in Listen state
while ( as3935.getState() != AS3935::stateListening ) as3935.process();
// process steps through initilization states

// delay ( dly );

if ( ! as3935.setNoiseFloor ( 0 ) ) {
Serial.println ( "Failed to set noise floor!" );
while ( 1 );
}
delay ( dly );

if ( 1 ) {
uint8_t val = 0xff;
if ( ! as3935.readRegister ( AS3935::regNoiseFloor , val ) ) {
Serial.println ( "Failed to read noise floor register!" );
while ( 1 );
}
val = ( val >> 4 ) & 0x07;
if ( val != 0 ) {
Serial.print ( "Problem - noise floor was set to 0 but didn't set ==> " );
Serial.println ( val );
}
while ( 1 );
}

// as3935.calibrate();
// delay ( 20 );
// set bit 5 of interrupt mask register to ignore disturbance events
as3935.setRegisterBit ( 0x03, 5, 1 );
delay ( 20 );

// set threshold number of strikes within 1 minute
// 0x00 -> 1; 0x01 -> 5; 0x02 -> 9; 0x03 -> 16 in bits 5-4 of register 2
as3935.setRegisterBit ( 0x02, 5, 0 );
delay ( 20 );
as3935.setRegisterBit ( 0x02, 4, 1 );
delay ( 20 );
// as3935.setMinimumLightnings ( 1 );

pinMode ( pdThrobber, OUTPUT );
digitalWrite ( pdThrobber, ledState );

pinMode ( piSensor, INPUT );
attachInterrupt ( intSensor, ISR_lightning_sensor, RISING );
throbberTimeout.start ( 1000, AsyncDelay::MILLIS );

if ( VERBOSE >= 2 ) {
textThrobberTimeout.start ( 10UL * 60UL * 1000UL, AsyncDelay::MILLIS );
}

#if VERBOSE >= 2

Serial.print ( "\n\nLightning Sensor [" );
Serial.print ( PROGNAME );
Serial.print ( "] v");
Serial.print ( VERSION );
Serial.print ( " (" );
Serial.print ( VERDATE );
Serial.print ( ")\n\n" );

displayRegs ();

#endif

}

void loop () {

int interruptFlags = -1;
int distanceEstimate = -1;
static int oldState = -1;

/*
AS3935 software state
stateOff = 0,
statePoweringUp = 1, // first 2ms wait after power applied
stateInitialising1 = 2,
stateInitialising2 = 3,
stateListening = 4,
stateWaitingForResult = 5,
stateCalibrate = 6,
*/
int state = as3935.getState();
if ( state != oldState ) {
for ( int i = 0; i < tabColumn; i++ ) Serial.print ( " " );
Serial.print ( "===> new state: " );
Serial.println ( states [ as3935.getState() ] );
oldState = state;
}

if ( as3935.process() ) {
interruptFlags = as3935.getInterruptFlags();
distanceEstimate = as3935.getDistance();

Serial.println ( "\n------ process -------" );
Serial.print ( "Interrupt flags: 0x" );
if ( interruptFlags < 0x10 ) Serial.print ( "0" );
Serial.print ( interruptFlags, HEX );
if ( distanceEstimate != 63 ) {
  Serial.print ( "; ( Distance: " );
  Serial.print ( distanceEstimate );
  Serial.print ( " km )" );
}
Serial.println ();

}

if (as3935.getBusError()) Serial.println ( "\nBus error!" );

if ( as3935.getTriggered() ) {

Serial.print ( "\n\n---------- triggered ----------\n" );

interruptFlags = as3935.getInterruptFlags ();
switch ( interruptFlags ) {
  case 0x01:
    if ( VERBOSE >= 10 ) displayRegs ( );
    Serial.print ( "Noise" );
    break;
  case 0x04:
    if ( VERBOSE >= 10 ) displayRegs ( );
    Serial.print ( "Disturber" );
    break;
  case 0x08:
    displayRegs ( );
    distanceEstimate = as3935.getDistance();
    Serial.print ( "Lightning at distance " );
    Serial.print ( distanceEstimate );
    Serial.print ( " km" );
    break;
  case -1:
    break;
  default:
    if ( VERBOSE >= 20 ) displayRegs ( );
    Serial.print ( "Something else" );
    break;
}
if ( interruptFlags >= 0 ) {
  Serial.println ( " happened!" );
  Serial.println("----------------------\n\n");
}

}

if (throbberTimeout.isExpired()) {
ledState = ! ledState;
digitalWrite ( pdThrobber, ledState );

if (++count > 5) {
  count = 0;
  // displayRegs ();
}
throbberTimeout.start(1000, AsyncDelay::MILLIS);

}

if ( VERBOSE >= 2 ) {
if (textThrobberTimeout.isExpired()) {
Serial.println ( "Still alive..." );
textThrobberTimeout.start ( 10UL * 60UL * 1000UL, AsyncDelay::MILLIS );
}
}

}

/**/
/
lightning sensor /
/
/

void ISR_lightning_sensor (void) {
as3935.interruptHandler();
}

void displayRegs () {

static bool firstTimeP = true;

Serial.print ( "\nAS3936 Registers as of " );
Serial.print ( millis() );
Serial.println ( " ms" );
/*
AS3935 registers
0x00 5-1 AFE_GB 0 PWD
AFE Gain Boost (norm 0x12 = 18)
Power-down (norm 0)
0x01 6-4 NF_LEV 3-0 WDTH
Noise Floor Level (norm 0)
Watchdog threshold (norm 2)
0x02 6 CL_STAT 5-4 MIN_NUM_LIGH 3-0 SREJ
Reg is usually 0xc2 (using a reserved bit!)
Clear statistics (norm 1)
Minimum number of lightning (norm 0)
Spike rejection (norm 2)
0x03 7-6 LCO_FDIV 5 MASK_DIST 3-0 INT
Frequency division ratio for antenna tuning (norm 0)
Mask Disturber (norm 0)
Interrupt (norm 0)

  0x04 S_LIG_L
    Energy of the single lightning LSByte
    
  0x05 S_LIG_M
    ... MSByte
  0x06 4-0 S_LIG_MM
    ... MMSByte
  0x07 5-0 DISTANCE
    Distance estimate (kilometers; norm 0x3f)
  0x08 7 DISP_LCO 6 DISP_SRCO 5 DISP_TRCO 3-0 TUN_CAP
    Display LCO on IRQ pin (norm 0)
    Display SRCO on IRQ pin (norm 0)
    Display TRCO on IRQ pin (norm 0)
    Internal tuning capacitors 0-120pF steps of 8pF (2)

*/

uint8_t val;

as3935.readRegister ( 0 , val );
Serial.print ( " AFE gain boost ( 0x12 ): " ); Serial.println ( ( val >> 1 ) & 0x1f, HEX );
Serial.print ( " Power-down ( 0 ): " ); Serial.println ( ( val >> 0 ) & 0x01, HEX );

as3935.readRegister ( 1 , val );
Serial.print ( " Noise Floor Level ( 0 ): " ); Serial.println ( ( val >> 4 ) & 0x03, HEX );
Serial.print ( " Watchdog threshold ( 2 ): " ); Serial.println ( ( val >> 0 ) & 0x0f, HEX );

as3935.readRegister ( 2 , val );
Serial.print ( " Clear statistics ( 1 ): " ); Serial.println ( ( val >> 6 ) & 0x01, HEX );
int num = ( ( val >> 4 ) & 0x03 );
int nums [] = { 1, 5, 9, 16 };
Serial.print ( " Minimum reportable strikes/min ( 0 ): " ); Serial.print ( num );
Serial.print ( " => " ); Serial.println ( nums [ num ] );
Serial.print ( " Spike rejection ( 2 ): " ); Serial.println ( ( val >> 0 ) & 0x0f, HEX );

as3935.readRegister ( 3 , val );
Serial.print ( " Frequency division ratio for antenna tuning ( 0 ): " );
Serial.println ( ( val >> 6 ) & 0x02, HEX );
Serial.print ( " Mask Disturber ( 0 ): " ); Serial.println ( ( val >> 5 ) & 0x01, HEX );
Serial.print ( " Interrupt ( 0 ): " ); Serial.println ( ( val >> 0 ) & 0x0f, HEX );

if ( ! firstTimeP ) {

// avoid printing residual values during startup 

unsigned long energy = 0;
as3935.readRegister ( 6 , val );
energy |= ( val & 0x0f );
energy <<= 4;
as3935.readRegister ( 5 , val );
energy |= ( val & 0xff );
energy <<= 8;
as3935.readRegister ( 4 , val );
energy |= ( val & 0xff );
if ( energy > 0 ) for ( int i = 0; i < tabColumn; i++ ) Serial.print ( " " );
Serial.print ( "  Energy of the single lightning: " ); Serial.println ( energy );

if ( energy > 0 ) {
  as3935.readRegister ( 7 , val );
  val = ( val >> 0 ) & 0x3f;
  if ( val < 0x3f ) for ( int i = 0; i < tabColumn; i++ ) Serial.print ( " " );
  Serial.print ( "  Distance estimate, km ( 63 ): " );
  Serial.print ( val );
}
Serial.println ();

}

/*
// no referent!
Serial.print("EIFR: ");
Serial.print ( EIFR < 0x10 ? "0x0" : "0x" );
Serial.println(EIFR, HEX);
*/
Serial.flush();

firstTimeP = false;

}

Will this work as a replacement for the Wiring library?

There is a Wiring library that is referenced for a specific board (Adafruit PCA 9685) I am trying to use, http://wiring.org.co/reference/libraries/Wire/index.html

Will SoftWire act as a replacement for that library? That is, assuming I change a few minor lines within that library, such as Wire.h --> SoftWire.h. That library is a pain because it does not easily import into the Arduino native environment, instead the "library" actually implements its own IDE on top of the Arduino IDE.

Can't compile example file

Hi Steve,

I am using this library to run on LoLin NODEMCU (ESP8266) which doesn't have hardware I2C.
When I try to compile example SoftWire_MLX90614 file, i get following compilation error.

Arduino: 1.8.5 (Windows 10), Board: "NodeMCU 0.9 (ESP-12 Module), 80 MHz, 115200, 4M (3M SPIFFS)"

Build options changed, rebuilding all
C:\Users\sumeetpatil\Documents\Arduino\libraries\SoftWire\src\SoftWire.cpp:1:25: fatal error: util/atomic.h: No such file or directory

#include <util/atomic.h>

                     ^

compilation terminated.

exit status 1
Error compiling for board NodeMCU 0.9 (ESP-12 Module).

Question:
Can the clock frequency set to 400KHz in this Library?

Regards,
Sumeet

Restart condition is not issued

Hi, thank you for the great work. I was trying to read the data with a restart condition like this.

uint8_t readByte(uint8_t address, uint8_t subAddress, SoftWire& wire) {
    wire.beginTransmission(address);
    wire.write(subAddress);
    wire.endTransmission(false);

    wire.requestFrom(address, (size_t)1);
    uint8_t data = 0;
    if (wire.available()) data = wire.read();

    return data;
}

A correct transaction with the Wire library looks like this.

Screen Shot 2021-06-22 at 20 13 32

But it seems that a restart condition is not issued with SoftWire. The hardware setup and code are exactly the same except for the use of SoftWire instead of Wire.

Screen Shot 2021-06-22 at 20 15 19

I've forced to use repeatedStart instead of start in Line 449 of SoftWire.h. Then I could issue a restart condition but the data was not correct.

Screen Shot 2021-06-23 at 19 43 33

Do you have any idea to work around this issue?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.