Open Tealons opened 8 years ago
Hi, please show your code here for evaluation.
Hi, I have assigned an engineer looking at this, will get back to you as soon as possible.
#include <Wire.h>
#define TXRX_BUF_LEN 20
BLE ble;
static boolean analog_enabled = false;
static byte old_state = LOW;
// The Nordic UART Service
static const uint8_t service1_uuid[] = {0x71, 0x3D, 0, 0, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
static const uint8_t service1_tx_uuid[] = {0x71, 0x3D, 0, 3, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
static const uint8_t service1_rx_uuid[] = {0x71, 0x3D, 0, 2, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
static const uint8_t uart_base_uuid_rev[] = {0x1E, 0x94, 0x8D, 0xF1, 0x48, 0x31, 0x94, 0xBA, 0x75, 0x4C, 0x3E, 0x50, 0, 0, 0x3D, 0x71};
uint8_t tx_value[TXRX_BUF_LEN] = {0,};
uint8_t rx_value[TXRX_BUF_LEN] = {0,};
GattCharacteristic characteristic1(service1_tx_uuid, tx_value, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE );
GattCharacteristic characteristic2(service1_rx_uuid, rx_value, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
GattCharacteristic *uartChars[] = {&characteristic1, &characteristic2};
GattService uartService(service1_uuid, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic *));
static void disconnectionCallBack(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
{
Serial1.println("Disconnected!");
Serial1.println("Restarting the advertising process");
ble.startAdvertising();
}
void setup() {
// put your setup code here, to run once
Serial1.begin(9600);
ble.init();
ble.onDisconnection(disconnectionCallBack);
// setup adv_data and srp_data
ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
(const uint8_t *)"BLAAT", sizeof("BLAAT") - 1);
ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
(const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid_rev));
// set adv_type
ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
// add service
ble.addService(uartService);
// set device name
ble.setDeviceName((const uint8_t *)"Simple Controls");
// set tx power,valid values are -40, -20, -16, -12, -8, -4, 0, 4
ble.setTxPower(4);
// set adv_interval, 100ms in multiples of 0.625ms.
ble.setAdvertisingInterval(160);
// set adv_timeout, in seconds
ble.setAdvertisingTimeout(0);
// start advertising
ble.startAdvertising();
Serial1.println("Advertising Start!");
Wire.begin();
Serial1.println("Wire.begin called");
}
void loop() {
ble.waitForEvent();
byte error, address;
int nDevices;
Serial1.println("Scanning for i2c device...");
nDevices = 0;
for(address = 1; address < 127; address++ )
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
uint8_t buf[3];
//send string to mobile and serial port to indicate that device is found.
Serial1.print("I2C device found at address 0x");
if (address<16)
Serial1.print("0");
Serial1.print(address,HEX);
Serial1.println(" !");
buf[0] = (0x74);
buf[1] = (0x65);
buf[2] = (0x73);
buf[3] = (0x74);
ble.updateCharacteristicValue(characteristic2.getValueAttribute().getHandle(), buf, 4);
nDevices++;
} else if (error==4){
//send string to mobile and serial port to indicate that device?? (or error) is found.
Serial1.print("Unknow error at address 0x");
if (address<16)
Serial1.print("0");
Serial1.println(address,HEX);
uint8_t buf[3];
buf[0] = (0x74);
buf[1] = (0x65);
buf[2] = (0x73);
buf[3] = (0x74);
ble.updateCharacteristicValue(characteristic2.getValueAttribute().getHandle(), buf, 4);
}
}
if (nDevices == 0){
Serial1.println("No I2C devices found\n");
uint8_t buf[3];
buf[0] = (0x6e);
buf[1] = (0x6f);
buf[2] = (0x74);
ble.updateCharacteristicValue(characteristic2.getValueAttribute().getHandle(), buf, 3);
}else{
uint8_t buf[3];
buf[0] = (0x74);
buf[1] = (0x6f);
buf[2] = (0x6e);
ble.updateCharacteristicValue(characteristic2.getValueAttribute().getHandle(), buf, 3);
Serial1.println("done\n");
}
delay(1000); // wait a second for next scan
}
The same code, with the ble specific parts commented out, is used on an Arduino Deumilanove. Works without a problem. To confirm the correct functioning of the Nano, I created a cordova app. The 'not' string is send, so the scanning code is executed.
On the Arduino I also have to replace the Serial1 with Serial.
Hi, thank you for pointing out this.
There is a fix to the I2C, changes SCL1 -> I2C_SCL0 and SDA1 -> I2C_SDA0 https://github.com/RedBearLab/nRF51822-Arduino/blob/S130/arduino-1.6.x/hardware/RBL/RBL_nRF51822/libraries/Wire/Wire.cpp
Would you mind to help testing it with your sensor?
We will release it with the board package to the Boards Manager soon.
It fixed the build error, but still no sensor detected. I'm on holiday at home, so plenty of time to help you fix this by Skype or something else...
which two pins do you use for the I2C ?
I have attached photo's of my setup. While I was making the photo's I wondered if I need to apply pull-up resistors? I don't need them on my Arduino, but maybe the Nano needs them?
In your photos, it looks correct (D2 and D3 for the I2C) Yes, you need pull up resistors for the I2C pins unless your sensor board has.
My Bad. The board has them: http://cdn.sparkfun.com/datasheets/Sensors/Pressure/BMP180%20breakout.pdf
I don't have a scope to check the signals... So what are the next steps to tackle this issue?
please hold on, my engineer is looking into this.
@Cheong2K Any news? Or an ETA when your engineer will have the library fixed?
Hi, he should have fixed, please check.
No change. Still not working. Please advise on the next steps...
Interestingly the pin numbers used by the wire.begin() function changed from 10 & 8 to 3 & 2 ??!! What's going on??
See RBL_nRF51822\variants\BLE_Nano\pins_arduino.h, TWI_SDA is D2 and TWI_SCL is D3.Throught function "Pin_nRF51822_to_Arduino",We get the P0.10 and P0.08. I test it with example "AT24C512_Demo", it work ok.
@zoujixing Yeah, I saw that too. I was more concerned with the commit earlier to fix the build error? Also, was the example not supposed to work from the beginning? I'm a little sceptical that it works now. Did you look at my code? Could you get it to work?
Same script, without the BLE stuff, with an Arduino Duemilanove setup in 2 minutes:
This should be just as easy with the Nano.... But now 5 days and counting to get this work.
Sorry for that, we have try our best.
It is too difficult to be 100% compatible for the BLE Nano (ARM) with the Atmel chips (AVR 8-bit) using your code posted. The lower layer driver from Nordic has its limitation.
@Tealons I have modified I2C library, try it by follow code :
for(index1=0; index1<127; index1++)
{
Wire.beginTransmission(index1);
err_code = Wire.endTransmission();
Serial1.print("The addr1 : ");
Serial1.println(index1, HEX);
if(err_code == -1)
Serial1.println("No slave device");
else if(err_code == -2)
Serial1.println("i2c bus busy");
else if(err_code == 0)
Serial1.println("i2c slave device exist");
Serial1.print("\r\n \r\n");
delay(500);
}
I will try the new code out tomorrow. I'm at a conference today. @Cheong2K Does it help if I switch to the mbed or Nordic environments instead of that of the Arduino?
I think so, they have a lot of engineers to support you.
Which one is the better pick in terms of support, examples and standard libraries?
If you are good at MCU development and you know how to setup the development environment, you should use Nordic SDK directly, this allows you to use latest development tools of Nordic. The problem is you have to use the low level API yourself. You need to pay for the compiler if you are going to use the Keil IDE.
mbed is an online development platform and you don't need to pay for the compiler, you don't need to setup any development environment and it has a lot of examples/libraries for you to use.
In terms of support, I can't say how good they can help but you can make use of their forum and you can also submit a case in Nordic's portal, they will provide support to you.
I now get a device on every address....
Any updates on this one? I find a similar issue with both a PN532 breakout, and a BNO055 breakout. NO_SLAVE. I tried to use several different pins, and update locations in pins_arduino.h to the correct values, as well as use the Wire.begin(SCL, SDA, TWI_SPEED) function to ensure correct pins. I've also connected two 4.7k pullups just in case. No luck :( I have the latest copy of the library with all the latest edits to overcome earlier issues such as address >> 1. Any help would be appreciated. How does the solution work for one board (the eeprom) but not another (PN532, a very common arduino breakout)?
There seems to be other mbed code out there which also has a TWI interface. Any learning from that code that can be applied to this?
SOLVED!
Scanning... I2C device found at address 0x24 ! I2C device found at address 0x28 ! 2I2C devices found
This is the things I had to change:
(GPIO_PIN_CNF_DRIVE_**S**0D1 << GPIO_PIN_CNF_DRIVE_Pos) |
NEW: (GPIO_PIN_CNF_DRIVE_**H**0D1 << GPIO_PIN_CNF_DRIVE_Pos) |
#ifdef BLE_NANO
switch(pin)
{
case 0 : return_pin = P0_11;break; //D0/RXD/MISO
case 1 : return_pin = P0_9;break; //D1/TXD/MOSI
case 2 : return_pin = P0_10;break; //D2/CTS/CS/SDA
case 3 : return_pin = P0_8;break; //D3/RTS/SCK/SCL
case 4 : return_pin = P0_28;break; //D4
case 5 : return_pin = P0_29;break; //D5
case 6 : return_pin = P0_15;break; //D6
case 7 : return_pin = P0_7;break; //D7
case 13 : return_pin = P0_19;break; //D13/LED
case 8 : return_pin = P0_1;break; //A0
case 9 : return_pin = P0_2;break; //A1
case 10 : return_pin = P0_3;break; //A2
case 11 : return_pin = P0_4;break; //A3
case 12 : return_pin = P0_5;break; //A4
case 14 : return_pin = P0_6;break; //A5
default : return_pin = (PinName)NC;break;
}
#endif
My SCL was connected to the conveniently available pad on the BLE Nano, P06, marked as '14' here. And the SDA was next to it, P07, marked as '7'
So I had to call the I2C initialization as:
Wire.begin(**14, 7,** TWI_FREQUENCY_100K);
@1vav I never found the time to digg deeper into the issue. So I'm glad you fixed it! I will try it out right away!
@Tealons , hope this works for you, just make sure to initialize your I2C with your particular pins. That file I posted above might have a different version for your download, so make sure to find the right pin transform file. Second, TWI libraries initialize Wire.begin() without SCL SDA overriding function. So make sure in every file in the hierarchy, the SCL and SDA are defined to your liking, or that at every hierarchy the Wire.begin(SCL,SDA,I2CSPEED) calls are used. It's classic bad coding issues seen at play here, hard-coding (SCL SDA and pin transform values), multiple code fragments doing the same thing (begin calls), and bad documentation (or lack thereof)
Hello 1vav, I have RBL nRF51822 board and i think i have the same issue with you but i cannot fix it. I'm using the latest Wire.h and Wire.cpp from here (https://developer.mbed.org/teams/RedBearLab/code/I2C_Demo/) and tried GPIO_PIN_CNFDRIVEH0D1 change, but no luck. I have 3 I2C devices connected on pins p5(SCL) and p4(SDA), and when i run the i2c scanner example i get "No I2C devices found". If you have any idea about this please help. Thank you.
Check all I2C chips/board schematics- SDA and SCL pins have pullup resistors. If all the pullups on a line are less than 4.7k together, it's possible the bus will fail. If so, remove the resistors such that the value goes up to 10k or so. That's just one possibility. Also, test the i2c devices one by one. I2c scanner is a great program for this. Also make sure the TWI is getting correctly initialized - often begin() functions cause the bus to default to some pins which may not be the correct ones. Use begin(scl, sda, twi_frequency) versions of the functions with the sda and scl pins correctly representing your wiring. Also note that pin '5' on code might map to a totally different port number on the nrf, like 0.12 or such. On Apr 7, 2016 4:25 PM, "Lilium JSN" notifications@github.com wrote:
Hello 1vav, I have RBL nRF51822 board and i think i have the same issue with you but i cannot fix it. I'm using the latest Wire.h and Wire.cpp from here ( https://developer.mbed.org/teams/RedBearLab/code/I2C_Demo/) and tried GPIO_PIN_CNF_DRIVE__H_0D1 change, but no luck. I have 3 I2C devices connected on pins p5(SCL) and p4(SDA), and when i run the i2c scanner example i get "No I2C devices found". If you have any idea about this please help. Thank you.
— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/RedBearLab/nRF51822-Arduino/issues/38#issuecomment-207135862
Thanks for your answer. To start with, can you please verify what Wire files' version did you use? It seems that this one for example (https://developer.mbed.org/teams/RedBearLab/code/I2C_Demo/file/0298ffee8eba/wire.cpp) is not using pin_transform. Total resistor pullup value is 10K and i've checked the schematics a hundred times today. arduinoPin23 should be SCL/nrfP0_5 and arduinoPin22 should be SDA/nrfP0_4. Here is my code: .ino
// --------------------------------------
// i2c_scanner
//
// Version 1
// This program (or code that looks like it)
// can be found in many places.
// For example on the Arduino.cc forum.
// The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
// Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26 2013
// V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
// by Arduino.cc user Krodal.
// Changes by louarnold removed.
// Scanning addresses changed from 0...127 to 1...119,
// according to the i2c scanner by Nick Gammon
// http://www.gammon.com.au/forum/?id=10896
// Version 5, March 28, 2013
// As version 4, but address scans now to 127.
// A sensor seems to use address 120.
// Version 6, November 27, 2015.
// Added waiting for the Leonardo serial communication.
//
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
//
#include <Wire.h>
#define pinSCL 23
#define pinSDA 22
#define pinEna 4
void setup()
{
pinMode(pinEna, OUTPUT);
digitalWrite(pinEna, HIGH);
Wire.begin(pinSCL, pinSDA, TWI_FREQUENCY_100K);
Serial.begin(9600);
while (!Serial); // Leonardo: wait for serial monitor
Serial.println("\nI2C Scanner");
}
void loop()
{
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for (address = 1; address < 127; address++ )
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address < 16)
Serial.print("0");
Serial.print(address, HEX);
Serial.println(" !");
nDevices++;
}
else if (error == 4)
{
Serial.print("Unknow error at address 0x");
if (address < 16)
Serial.print("0");
Serial.println(address, HEX);
}
}
if (nDevices == 0){
Serial.println("No I2C devices found\n");
Serial.print("Last address:");
Serial.println(address);
}
else
Serial.println("done\n");
delay(5000); // wait 5 seconds for next scan
}
wire.cpp
/*
Copyright (c) 2014 RedBearLab, All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "Wire.h"
/**********************************************************************
name :
function :
**********************************************************************/
TwoWire::TwoWire() :
RX_BufferHead(0), RX_BufferTail(0),
TX_BufferHead(0), TX_BufferTail(0),
Transfer_Addr(0),
i2c(),
twi_status(UNINITIALIZED)
{
//do nothing
}
/**********************************************************************
name :
function :
**********************************************************************/
void TwoWire::begin(uint32_t scl, uint32_t sda, uint32_t speed)
{
PinName nrf_sda, nrf_scl;
nrf_scl = Pin_nRF51822_to_Arduino(scl);
nrf_sda = Pin_nRF51822_to_Arduino(sda);
/* Initialize i2c */
i2c_init(&i2c, nrf_sda, nrf_scl);
i2c_frequency(&i2c, speed);
twi_status = UNINITIALIZED;
}
/**********************************************************************
name :
function :
**********************************************************************/
void TwoWire::begin()
{
PinName nrf_sda, nrf_scl;
nrf_scl = Pin_nRF51822_to_Arduino(TWI_SCL);
nrf_sda = Pin_nRF51822_to_Arduino(TWI_SDA);
/* Initialize i2c, default 100KHz */
i2c_init(&i2c, nrf_sda, nrf_scl);
twi_status = UNINITIALIZED;
}
/**********************************************************************
name :
function :
note : address has been shift right one bit, so need to shift left one bit
**********************************************************************/
void TwoWire::beginTransmission( uint8_t address )
{
Transfer_Addr = (address << 1);
TX_BufferTail = 0;
TX_BufferHead = 0;
twi_status = MASTER_SEND;
}
/**********************************************************************
name :
function :
**********************************************************************/
void TwoWire::beginTransmission( int address )
{
beginTransmission( (uint8_t)address );
}
/**********************************************************************
name :
function :
return : 0 success, -1 no slave, -2 bus busy
**********************************************************************/
int8_t TwoWire::endTransmission( uint8_t stop)
{
int8_t result=0;
result = i2c_write(&i2c, Transfer_Addr, (const char *)TX_Buffer, TX_BufferHead, stop);
TX_BufferHead = 0;
twi_status = MASTER_IDLE;
if(i2c.i2c->EVENTS_ERROR == 1) {
if (i2c.i2c->ERRORSRC & TWI_ERRORSRC_ANACK_Msk) {
i2c.i2c->EVENTS_ERROR = 0;
i2c.i2c->TASKS_STOP = 1;
result = I2C_ERROR_NO_SLAVE;
}
else if(i2c.i2c->ERRORSRC & TWI_ERRORSRC_DNACK_Msk) {
i2c.i2c->EVENTS_ERROR = 0;
i2c.i2c->TASKS_STOP = 1;
result = I2C_ERROR_BUS_BUSY;
}
}
if(stop)
i2c_reset(&i2c);
return result;
}
/**********************************************************************
name :
function :
**********************************************************************/
int8_t TwoWire::endTransmission(void)
{
int8_t result;
result = endTransmission(1);
return result;
}
/**********************************************************************
name :
function :
return : 0:full or error status
1:success
**********************************************************************/
size_t TwoWire::write(uint8_t data)
{
if(twi_status == MASTER_SEND) {
if(TX_BufferHead >= BUFF_MAX_LENGTH) {
return 1;
}
TX_Buffer[TX_BufferHead++] = data;
return 0;
}
else {
return 1;
}
}
/**********************************************************************
name :
function :
return : 0 : full or error status
other : the true size of write
**********************************************************************/
size_t TwoWire::write(const uint8_t *data, size_t quantity )
{
size_t index;
if( twi_status == MASTER_SEND ) {
for( index=0; index<quantity; ++index ) {
if(TX_BufferHead >= BUFF_MAX_LENGTH) {
return index;
}
TX_Buffer[TX_BufferHead++] = data[index];
}
}
else {
return 0;
}
return quantity;
}
/**********************************************************************
name :
function :
return : 0 : error
other : the true size of read
**********************************************************************/
uint8_t TwoWire::requestFrom(uint8_t addr, uint8_t quantity, uint8_t stop)
{
uint8_t result;
Transfer_Addr = (addr << 1);
if(quantity > BUFF_MAX_LENGTH) {
quantity = BUFF_MAX_LENGTH;
}
if(quantity > 0 ) {
result = i2c_read(&i2c, Transfer_Addr, (char *)RX_Buffer, quantity, stop);
}
RX_BufferTail = 0;
RX_BufferHead = result;
return result;
}
/**********************************************************************
name :
function :
**********************************************************************/
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
{
return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) true);
}
/**********************************************************************
name :
function :
**********************************************************************/
uint8_t TwoWire::requestFrom(int address, int quantity)
{
return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) true);
}
/**********************************************************************
name :
function :
**********************************************************************/
uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop)
{
return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) sendStop);
}
/**********************************************************************
name :
function :
**********************************************************************/
int TwoWire::available(void)
{
if(RX_BufferTail <= RX_BufferHead) {
return (RX_BufferHead - RX_BufferTail);
}
else {
return 0;
}
}
/**********************************************************************
name :
function :
**********************************************************************/
int TwoWire::read(void)
{
if(RX_BufferTail < RX_BufferHead) {
return RX_Buffer[RX_BufferTail++];
}
else {
return -1;
}
}
/**********************************************************************
name :
function :
**********************************************************************/
int TwoWire::peek(void)
{
if(RX_BufferTail < RX_BufferHead) {
return RX_Buffer[RX_BufferTail];
}
else {
return -1;
}
}
/**********************************************************************
name :
function :
**********************************************************************/
void TwoWire::flush(void)
{
//do nothing
}
TwoWire Wire;
wire.h
/*
Copyright (c) 2014 RedBearLab, All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _WIRE_H_
#define _WIRE_H_
#include "WStream.h"
#include "Arduino.h"
#define BUFF_MAX_LENGTH 32
#define TWI_FREQUENCY_100K 100000
#define TWI_FREQUENCY_250K 250000
#define TWI_FREQUENCY_400K 400000
class TwoWire : public WStream
{
public :
enum TwoWireStatus {
UNINITIALIZED,
MASTER_IDLE,
MASTER_SEND,
MASTER_RECV,
SLAVE_IDLE,
SLAVE_RECV,
SLAVE_SEND
};
protected :
uint8_t RX_Buffer[BUFF_MAX_LENGTH];
uint8_t RX_BufferHead;
uint8_t RX_BufferTail;
uint8_t TX_Buffer[BUFF_MAX_LENGTH];
uint8_t TX_BufferHead;
uint8_t TX_BufferTail;
uint8_t Transfer_Addr;
i2c_t i2c;
TwoWireStatus twi_status;
public :
TwoWire();
void begin();
void begin(uint32_t scl_pin, uint32_t sda_pin, uint32_t speed);
void beginTransmission(uint8_t);
void beginTransmission(int);
int8_t endTransmission(void);
int8_t endTransmission(uint8_t);
uint8_t requestFrom(uint8_t, uint8_t);
uint8_t requestFrom(uint8_t, uint8_t, uint8_t);
uint8_t requestFrom(int, int);
uint8_t requestFrom(int, int, int);
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *, size_t);
virtual int available(void);
virtual int read(void);
virtual int peek(void);
virtual void flush(void);
inline size_t write(unsigned long n) { return write((uint8_t)n); }
inline size_t write(long n) { return write((uint8_t)n); }
inline size_t write(unsigned int n) { return write((uint8_t)n); }
inline size_t write(int n) { return write((uint8_t)n); }
using Print::write;
};
extern TwoWire Wire;
#endif
So there's a difference between Wire.h and wire.h as far as I know, you're include and actual file don't match our seems to me. I use the default Wire.h not the mbed wire.h. Honestly I don't remember where I downloaded from.
Also the address << 1, try changing that to just address in the begin transmission function if you use that library. On Apr 7, 2016 5:23 PM, "Lilium JSN" notifications@github.com wrote:
Thanks for your answer. To start with, can you please verify what Wire files' version did you use? It seems that this one for example ( https://developer.mbed.org/teams/RedBearLab/code/I2C_Demo/file/0298ffee8eba/wire.cpp) is not using pin_transform. Total resistor pullup value is 10K and i've checked the schematics a hundred times today. arduinoPin23 should be nrfP0_5 and arduinoPin22 should be nrfP04. Here is my code: .ino_
// -------------------------------------- // i2c_scanner // // Version 1 // This program (or code that looks like it) // can be found in many places. // For example on the Arduino.cc forum. // The original author is not know. // Version 2, Juni 2012, Using Arduino 1.0.1 // Adapted to be as simple as possible by Arduino.cc user Krodal // Version 3, Feb 26 2013 // V3 by louarnold // Version 4, March 3, 2013, Using Arduino 1.0.3 // by Arduino.cc user Krodal. // Changes by louarnold removed. // Scanning addresses changed from 0...127 to 1...119, // according to the i2c scanner by Nick Gammon // http://www.gammon.com.au/forum/?id=10896 // Version 5, March 28, 2013 // As version 4, but address scans now to 127. // A sensor seems to use address 120. // Version 6, November 27, 2015. // Added waiting for the Leonardo serial communication. // // // This sketch tests the standard 7-bit addresses // Devices with higher bit address might not be seen properly. //
include
define pinSCL 23
define pinSDA 22
define pinEna 4
void setup() { pinMode(pinEna, OUTPUT); digitalWrite(pinEna, HIGH); Wire.begin(pinSCL, pinSDA, TWI_FREQUENCY_100K);
Serial.begin(9600); while (!Serial); // Leonardo: wait for serial monitor Serial.println("\nI2C Scanner"); }
void loop() { byte error, address; int nDevices;
Serial.println("Scanning...");
nDevices = 0; for (address = 1; address < 127; address++ ) { // The i2c_scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. Wire.beginTransmission(address); error = Wire.endTransmission();
if (error == 0) { Serial.print("I2C device found at address 0x"); if (address < 16) Serial.print("0"); Serial.print(address, HEX); Serial.println(" !"); nDevices++; } else if (error == 4) { Serial.print("Unknow error at address 0x"); if (address < 16) Serial.print("0"); Serial.println(address, HEX); }
} if (nDevices == 0){ Serial.println("No I2C devices found\n"); Serial.print("Last address:"); Serial.println(address); } else Serial.println("done\n");
delay(5000); // wait 5 seconds for next scan }
wire.cpp
/ Copyright (c) 2014 RedBearLab, All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /
include "Wire.h"
/** name : function : _/ TwoWire::TwoWire() : RX_BufferHead(0), RX_BufferTail(0), TX_BufferHead(0), TX_BufferTail(0), Transfer_Addr(0), i2c(), twi_status(UNINITIALIZED) { //do nothing } /_ name : function : **/ void TwoWire::begin(uint32_t scl, uint32_t sda, uint32_t speed) { PinName nrf_sda, nrf_scl;
nrf_scl = Pin_nRF51822_to_Arduino(scl); nrf_sda = Pin_nRF51822_to_Arduino(sda); /* Initialize i2c */ i2c_init(&i2c, nrf_sda, nrf_scl); i2c_frequency(&i2c, speed); twi_status = UNINITIALIZED;
} /** name : function : **/ void TwoWire::begin() { PinName nrf_sda, nrf_scl;
nrf_scl = Pin_nRF51822_to_Arduino(TWI_SCL); nrf_sda = Pin_nRF51822_to_Arduino(TWI_SDA); /* Initialize i2c, default 100KHz */ i2c_init(&i2c, nrf_sda, nrf_scl); twi_status = UNINITIALIZED;
} /** name : function : note : address has been shift right one bit, so need to shift left one bit _/ void TwoWire::beginTransmission( uint8_t address ) { Transfer_Addr = (address << 1); TX_BufferTail = 0; TX_BufferHead = 0; twi_status = MASTER_SEND; } /_ name : function : _/ void TwoWire::beginTransmission( int address ) { beginTransmission( (uint8_t)address ); } /_ name : function : return : 0 success, -1 no slave, -2 bus busy **/ int8_t TwoWire::endTransmission( uint8_t stop) { int8_t result=0;
result = i2c_write(&i2c, Transfer_Addr, (const char *)TX_Buffer, TX_BufferHead, stop); TX_BufferHead = 0; twi_status = MASTER_IDLE; if(i2c.i2c->EVENTS_ERROR == 1) { if (i2c.i2c->ERRORSRC & TWI_ERRORSRC_ANACK_Msk) { i2c.i2c->EVENTS_ERROR = 0; i2c.i2c->TASKS_STOP = 1; result = I2C_ERROR_NO_SLAVE; } else if(i2c.i2c->ERRORSRC & TWI_ERRORSRC_DNACK_Msk) { i2c.i2c->EVENTS_ERROR = 0; i2c.i2c->TASKS_STOP = 1; result = I2C_ERROR_BUS_BUSY; } } if(stop) i2c_reset(&i2c); return result;
} /** name : function : **/ int8_t TwoWire::endTransmission(void) { int8_t result;
result = endTransmission(1); return result;
} /** name : function : return : 0:full or error status 1:success _/ size_t TwoWire::write(uint8_t data) { if(twi_status == MASTER_SEND) { if(TX_BufferHead >= BUFF_MAX_LENGTH) { return 1; } TX_Buffer[TX_BufferHead++] = data; return 0; } else { return 1; } } /_ name : function : return : 0 : full or error status other : the true size of write **/ size_t TwoWire::write(const uint8_t *data, size_t quantity ) { size_t index;
if( twi_status == MASTER_SEND ) { for( index=0; index<quantity; ++index ) { if(TX_BufferHead >= BUFF_MAX_LENGTH) { return index; } TX_Buffer[TX_BufferHead++] = data[index]; } } else { return 0; } return quantity;
} /** name : function : return : 0 : error other : the true size of read **/ uint8_t TwoWire::requestFrom(uint8_t addr, uint8_t quantity, uint8_t stop) { uint8_t result;
Transfer_Addr = (addr << 1); if(quantity > BUFF_MAX_LENGTH) { quantity = BUFF_MAX_LENGTH; } if(quantity > 0 ) { result = i2c_read(&i2c, Transfer_Addr, (char *)RX_Buffer, quantity, stop); } RX_BufferTail = 0; RX_BufferHead = result; return result;
} /** name : function : _/ uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) { return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) true); } /_ name : function : _/ uint8_t TwoWire::requestFrom(int address, int quantity) { return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) true); } /_ name : function : _/ uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop) { return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) sendStop); } /_ name : function : _/ int TwoWire::available(void) { if(RX_BufferTail <= RX_BufferHead) { return (RX_BufferHead - RX_BufferTail); } else { return 0; } } /_ name : function : _/ int TwoWire::read(void) { if(RX_BufferTail < RX_BufferHead) { return RX_Buffer[RX_BufferTail++]; } else { return -1; } } /_ name : function : _/ int TwoWire::peek(void) { if(RX_BufferTail < RX_BufferHead) { return RX_Buffer[RX_BufferTail]; } else { return -1; } } /_ name : function : **/ void TwoWire::flush(void) { //do nothing }
TwoWire Wire;
wire.h
/ Copyright (c) 2014 RedBearLab, All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /
ifndef _WIREH
define _WIREH
include "WStream.h"
include "Arduino.h"
define BUFF_MAX_LENGTH 32
define TWI_FREQUENCY_100K 100000
define TWI_FREQUENCY_250K 250000
define TWI_FREQUENCY_400K 400000
class TwoWire : public WStream { public :
enum TwoWireStatus { UNINITIALIZED, MASTER_IDLE, MASTER_SEND, MASTER_RECV, SLAVE_IDLE, SLAVE_RECV, SLAVE_SEND }; protected : uint8_t RX_Buffer[BUFF_MAX_LENGTH]; uint8_t RX_BufferHead; uint8_t RX_BufferTail; uint8_t TX_Buffer[BUFF_MAX_LENGTH]; uint8_t TX_BufferHead; uint8_t TX_BufferTail; uint8_t Transfer_Addr; i2c_t i2c; TwoWireStatus twi_status; public : TwoWire(); void begin(); void begin(uint32_t scl_pin, uint32_t sda_pin, uint32_t speed); void beginTransmission(uint8_t); void beginTransmission(int); int8_t endTransmission(void); int8_t endTransmission(uint8_t); uint8_t requestFrom(uint8_t, uint8_t); uint8_t requestFrom(uint8_t, uint8_t, uint8_t); uint8_t requestFrom(int, int); uint8_t requestFrom(int, int, int); virtual size_t write(uint8_t); virtual size_t write(const uint8_t *, size_t); virtual int available(void); virtual int read(void); virtual int peek(void); virtual void flush(void); inline size_t write(unsigned long n) { return write((uint8_t)n); } inline size_t write(long n) { return write((uint8_t)n); } inline size_t write(unsigned int n) { return write((uint8_t)n); } inline size_t write(int n) { return write((uint8_t)n); } using Print::write;
};
extern TwoWire Wire;
endif
— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/RedBearLab/nRF51822-Arduino/issues/38#issuecomment-207147571
Hi,
I'm trying to get an i2c sensor (the BMP180 from Sparkfun) up and running for the past few days with the arduino environment. However, without any luck. On an arduino I get it up and running in 5 minutes, but with the nano it has been nothing but trouble the past couple of days.
The first feeling I got that something might be wrong is the fact that the compiler gives the error that SCL1 and SDA1 are not defined. Seems like the wire.h implementation is messy and not well tested. Searching on your support forum gave no real help. All the answers there are short and not really helpfull. Scanning with an i2c scanner always give the same result... Device not found.
Please provide a working implementation of wire.h so I can hook up my i2c sensor. From the other issues that are posted the past couple of days, it seems that you have some serious issues with the arduino implementation..