I have the following queries regarding BLE peripheral on Arduino 101 :
Is is possible to advertise any characteristic value(dynamic data) rather than the UUID in the advertising packet. If so what are the APIs for that? My goal is to get any temperature data in the adv packet instead of connecting to the peripheral.
Current Observation: I was only able to advertise service uuids and local name using the APIs setAdvertisedServiceUuid and setLocalName.
2.In the following code I was able to start and capture the advertisement in the first instance but in the letter instance the begin had a false return value. Am I doing anything wrong? The idea is to start and stop the advertisement and may be even change the advertisement data.
#include <CurieBle.h>
void setup() {
// set LED pin to output mode
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
//BLE Peripheral
BLEPeripheral * blePeripheral = new BLEPeripheral;
//Set the Local Name
blePeripheral->setLocalName("MyDevice");
//Start Advertising
blePeripheral->begin();
//Run the advertisement for 20 seconds
delay(20000);
//Stop the advertisement
blePeripheral->end();
//Delete the BLE Peripheral
delete blePeripheral;
//Wait 5 seconds before starting the next adv
delay(5000);
}
Any help will be appreciated.
Thanks.
Swaroop
BLEPeripheral blePeripheral; // BLE Peripheral Device (the board you're programming)
BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // BLE LED Service
// BLE LED Switch Characteristic - custom 128-bit UUID, read and writable by central
BLEUnsignedCharCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
https://www.arduino.cc/en/Reference/BLEPeripheralConstructor
Related
I own an EEPROM module with the P24C256 chip. (not AT24C256).
After scanning for available I2C devices, i got response from two devices.
Scanning...
I2C device found at address 0x50 !
I2C device found at address 0x58 !
done
I looked up the datasheet, but cannot find any additional information.
I thought that the device, has two banks for storage, but that does not seem to be the case.
How is this possible? After disconnecting the module, no I2C devices are reported.
#include <Wire.h>
void setup()
{
Wire.begin();
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("Unknown error at address 0x");
if (address<16)
Serial.print("0");
Serial.println(address,HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");
delay(5000); // wait 5 seconds for next scan
}
Yes they can.
Depending on the size of the i2C EEPROM and how the memory blocks are organized you can have 2 or more device address. For example the ST24/25x04 EEPROM are 4 Kbit electrically erasable programmable memories, organized as 2 blocks of 256 x8 bits. That means that I2C gives you two device addresses (0x50 and 0x51 in the memory above), that will access each block with 1 byte address.
It might be the problem with the EEPROM address bits, in case they are in floating state and not connected properly, Could you please check the connections on those address bits? Try to connect them to the same ground as your micro-controller, but yes, as advised above, schematics is highly needed.
That behavior is not implied to by. The datasheet says the address should be only one (but its three lower bits can be chosen).
The schematics for the boards shows only two bits (A0, A1) are selected by the dip-switch, and A2 is tied to the ground.
I see no initialization in the code. What frequency the TWI bus is working at? Also, in the pictures of the module it has jumpers to pull-up resistors unsoldered, and it has 10kOhm pull-up resistors even if jumpers are soldered - that may be too high.
Probably you have issue just because the wire is not returned to the high level fast enough.
Check pull-up resistors are engaged (jumpers are soldered on the board)
Try to add additional pull-ups (about 4.7k) on SCL, SDA
Try to set lower frequency, e.g. Wire.setClock(50000);
I'm unable to use I2C on an ARM CORTEX M3 process.
What am I doing wrong? Which test could I perform to find the problem?
It is a GD32F130C8 (master) and I'm programming it with KEIL (using the GD32F1x0 Firmware Library)
The slave is a MPU-6050 (accelorometer)
I defined the variable with local address and MPU-6050 device:
#define I2C_ACCELEROMETER_ADDRESS 0xD0 //( 0x68 + one bit)
#define I2C_OWN_ADDRESS 0x72
Then I initialized the I2C PIN this way:
//Init I2C communication to accelerometer
// enable I2C0 clock
rcu_periph_clock_enable(RCU_I2C0);
// connect PB8 to I2C0_SCL
gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_8);
// connect PB9 to I2C0_SDA
gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_9);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_8);
gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_8);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_9);
gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_9);
Then I initialized the I2C this way:
void I2C_Accelerometer_init(void){
// configure I2C0 clock
i2c_clock_config(I2C0, 100000, I2C_DTCY_2);
// configure I2C0 address
i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C_OWN_ADDRESS);
// enable I2C0
i2c_enable(I2C0);
// enable acknowledge
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
}
Then periodically (each second) I try to get the data from the accelerometer.
There is no error but the variable "accelerometer_x_high" is always zero (this is basically my problem).
The following code is executed each second. As you can see I set power management to 0, then I request register with accelerometer data, then I try to get the data from the slave device:
extern uint8_t Accelerometer_X_High;
//periodically called by timers in it.c
void GetAccelerometerData(void){
uint8_t bytesToReadIndex=0;
//WAKE UP ACCELEROMETER (6B 00)
// wait until I2C bus is idle
while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY));
// send a start condition to I2C bus
i2c_start_on_bus(I2C0);
// wait until SBSEND bit is set
while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND));
// send slave address to I2C bus
i2c_master_addressing(I2C0, I2C_ACCELEROMETER_ADDRESS, I2C_TRANSMITTER);
// wait until ADDSEND bit is set
while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND));
// clear ADDSEND bit
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
// send a data byte
i2c_data_transmit(I2C0,0x6B); //PWR MANAGEMENT
// wait until the transmission data register is empty
while(!i2c_flag_get(I2C0, I2C_FLAG_TBE));
// send a data byte
i2c_data_transmit(I2C0,0x00); //WAKE UP
// wait until the transmission data register is empty
while(!i2c_flag_get(I2C0, I2C_FLAG_TBE));
// send a stop condition to I2C bus
i2c_stop_on_bus(I2C0);
while(I2C_CTL0(I2C0)&0x0200);
//REQUEST ACELEROMETER DATA (3B )
// wait until I2C bus is idle
while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY));
// send a start condition to I2C bus
i2c_start_on_bus(I2C0);
// wait until SBSEND bit is set
while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND));
// send slave address to I2C bus
i2c_master_addressing(I2C0, I2C_ACCELEROMETER_ADDRESS, I2C_TRANSMITTER);
// wait until ADDSEND bit is set
while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND));
// clear ADDSEND bit
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
// send a data byte
i2c_data_transmit(I2C0,0x3B); //ACCELEROMETER REGISTER
// wait until the transmission data register is empty
while(!i2c_flag_get(I2C0, I2C_FLAG_TBE));
// send a stop condition to I2C bus
i2c_stop_on_bus(I2C0);
while(I2C_CTL0(I2C0)&0x0200);
//now reopen the bus to receive the reply
// wait until I2C bus is idle
while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY));
// send a start condition to I2C bus
i2c_start_on_bus(I2C0);
// wait until SBSEND bit is set
while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND));
// send slave address to I2C bus
i2c_master_addressing(I2C0, I2C_ACCELEROMETER_ADDRESS, I2C_RECEIVER);
// wait until ADDSEND bit is set
while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND));
// if we receive only one byte: reset ACKEN bit
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
//clear ADDSEND bit
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
// if we receive only one byte: send stop condition
i2c_stop_on_bus(I2C0);
/* wait until the RBNE bit is set */
while(!i2c_flag_get(I2C0, I2C_FLAG_RBNE));
//read a data from I2C_DATA
Accelerometer_X_High = i2c_data_receive(I2C0);
// if we receive more bytes: send a stop condition to I2C bus
//i2c_stop_on_bus(I2C0);
while(I2C_CTL0(I2C0)&0x0200);
// enable acknowledge
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
}
acquiring signals with oscilloscope I get the following result:
this is a screenshot with entire signal:
http://www.tr3ma.com/Dati/IMG_1526.JPG
On the signal there are also strange spikes:
http://www.tr3ma.com/Dati/spike1.JPG
http://www.tr3ma.com/Dati/spike2.JPG
http://www.tr3ma.com/Dati/spike3.JPG
http://www.tr3ma.com/Dati/spike4.JPG
It works. I created a loop to read all the registers and I was able to read the entire content of the chip. There is no error on the firmware. The only problem is that the chip is not the one that I supposed it to be. I have to find the right part number of accelerometer and find the register to wake it up.
Before you mark this question as duplicate, please note that I have already tried this, this & this
I bought an Arduino UNO R3 & a SIM808 GSM/GPS shield recently. The RX of the Shield is connected to Pin 11 of Arduino, TX to Pin 10 with both the GNDs connected to each other. I have connected my Arduino to my computer with the USB & the shield is connected to an external power supply with a 12V Adapter. Additionally, I have connected the 3.3V of the Arduino to Vcc of the shield.
Following is the sketch I have used:
// Include the GSM library
#include <GSM.h>
#define PINNUMBER ""
// initialize the library instance
GSM gsmAccess;
GSM_SMS sms;
void setup() {
// initialize serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println("SMS Messages Sender");
// connection state
boolean notConnected = true;
// Start GSM shield
// If your SIM has PIN, pass it as a parameter of begin() in quotes
while (notConnected) {
if (gsmAccess.begin(PINNUMBER) == GSM_READY) {
notConnected = false;
} else {
Serial.println("Not connected");
delay(1000);
}
}
Serial.println("GSM initialized");
}
void loop() {
Serial.print("Enter a mobile number: ");
char remoteNum[20]; // telephone number to send sms
readSerial(remoteNum);
Serial.println(remoteNum);
// sms text
Serial.print("Now, enter SMS content: ");
char txtMsg[200];
readSerial(txtMsg);
Serial.println("SENDING");
Serial.println();
Serial.println("Message:");
Serial.println(txtMsg);
// send the message
sms.beginSMS(remoteNum);
sms.print(txtMsg);
sms.endSMS();
Serial.println("\nCOMPLETE!\n");
}
/*
Read input serial
*/
int readSerial(char result[]) {
int i = 0;
while (1) {
while (Serial.available() > 0) {
char inChar = Serial.read();
if (inChar == '\n') {
result[i] = '\0';
Serial.flush();
return 0;
}
if (inChar != '\r') {
result[i] = inChar;
i++;
}
}
}
}
Problem here is same as that mentioned in those linked posts.
The condition if (gsmAccess.begin(PINNUMBER) == GSM_READY) never gets executed. Neither does the else part execute.
Serial monitor never goes past SMS Messages Sender.
Please note that I am using AirTel India, I have a fully activated Data Plan & the PIN Number has been changed to 0000.
Would really appreciate if someone could suggest something helpful.
Thanks for your time!!
You cannot power a GSM module from the 3.3V of Arduino! a GSM needs peak currents of 3A (yes, Amps, not milli-amperes). You really need a LiPo battery to power the GSM. You could power a 3V Arduino from the same LiPo battery, actually, if you need a mobile solution, but not the other way around.
Please first check if the module responds with the next code Example Code
Other thing the Supply voltage range must be 3.4 ~ 4.4V, try not using less voltage .
The GSM library of the Arduino is for the Quectel M10 GSM/GPRS module and is not compatible with SimCom SIMxxx modules.
Here is the library that you can use for your SIM808 module https://github.com/MarcoMartines/GSM-GPRS-GPS-Shield (examples included in the repo). Note that this library uses the SIM900 library which allows low level interface with SimCom modules.
For further reading here two adafruit links:
http://wiki.iteadstudio.com/SIM808_GSM/GPRS/GPS_Module
https://www.adafruit.com/products/2637
the shield is connected to an external power supply with a 12V
Adapter. Additionally, I have connected the 3.3V of the Arduino to Vcc
of the shield.
What do you mean by that? You need to supply your shield with the required voltage that can deliver the required amps. And also you need to have a common ground with your arduino.
In addition, if your shield is a 3.3V you need to shift Tx line comming from arduino as well (because it's a 5V) using a voltage divider.
Note that these shields have also a soft power-up button that needs to be connected as well, to allow the code to power up your module.
Is it possible to communicate between two ATtiny85? I can use my Arduino to communicate with ATtiny85 by using Arduino Uno as the master and ATtiny85 as a slave. But I want to use one ATtiny85 as the master and one as a slave. Is this possible ?
I am not able to understand the examples given in TinyWireM library. I want a simple master and slave code for communication. For example, master should ask for 1 integer value and slave should reply.
My slave code :
#define I2C_SLAVE_ADDRESS 0x14 // Address of the slave
#include <TinyWireS.h>
int i=0;
void setup()
{
TinyWireS.begin(I2C_SLAVE_ADDRESS); // join i2c network
TinyWireS.onRequest(requestEvent);
}
void loop()
{
TinyWireS_stop_check();
}
void requestEvent()
{
if(i==1000)
{
TinyWireS.send(1);
i=0;
}
else
i++;
}
My master code
#include <TinyWireM.h>
#define DS1621_ADDR 0x14
void setup()
{
TinyWireM.begin();
pinMode(4, OUTPUT);
}
void loop()
{
TinyWireM.requestFrom(DS1621_ADDR,4); // Request 1 byte from slave
int tempC = TinyWireM.receive();
if(tempC)
{
digitalWrite(4, HIGH);
delay(1000); // wait for a second
digitalWrite(4, LOW);
delay(1000); // wait for a second
}
if(tempC>1)
{
digitalWrite(4, HIGH);
delay(1000); // wait for a second
digitalWrite(4, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
}
I tried the above code but still I cannot see the LED blinking. But if I keep slave code as it is and use the following master code on an Arduino then everything works fine.
Arduino Uno code as master.
#include <Wire.h>
float i1=-1, i2=-1;
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial for output
}
void loop()
{
Wire.requestFrom(4, 1); // request 1 byte from slave address 4
while(Wire.available()) // slave may send less than requested
{
i1 = Wire.read(); // receive a byte as character
Serial.println(i1); // print the character
}
}
connection is and connections are SDA to SCL pins
pin 5 of master attiny85 - pin 7 of slave attiny85
pin 7 of slave attiny85 - pin 5 of master attiny85
I also tried by no cross connecting them. example and connections are SDA to SDA pins
pin 5 of master attiny85 - pin 5 of slave attiny85
pin 7 of slave attiny85 - pin 7 of master attiny85
but still no success.
Yes, it is possible to use 1 ATtiny85 as a master, and another as a slave. The TinyWireM and TinyWireS libraries are both well-written and easy to use.
Handling a request and sending back bytes is as simple as setting the onRequest slave read event handler to a function of your choice that sends the correct data back. There are examples of this in the TinyWireS library.
Did you use the pull-up resistor for both, the SDA and SCL? They are important for the I2C protocol.
FYI: The logic '0' on the either bus is set by device driving actual '0' on the pin. On the other hand, the logic '1' is set on the bus by putting the device pin in the high impedance, in case on the ATtiny, it means setting pin into INPUT direction. When the both, the master and slave set pins to hiZ, the pull-up resistor pulls the voltage on the bus to value representing logic '1'. This solution allows avoiding contention on bi-directional bus (one device driving '1' and second driving '0') than can lead to short-circuit and damaging devices. So, if you don't use the pull-up resistor, the bus will be left floating whenever logic '1' is driven and it will lead to protocol errors.
I just bought an Intel Edison Breakout Board Kit with the Grove Starter Kit Plus I want to write a program which gives the board an IP address, checks for a temperature in a room and if that temperature is exceeded it turns a LED on. I can check what's going on with a RGB display. When I connect the USB OTG port to the my laptop the wifi connection is perfectly detected, the IP address is perfectly received and the temperature control works fine. The program works as I ask for. Now the questions. I would like to execute the same program unplugging the USB connection, so I would like to make this board independent from PC, like if it is a standing alone device
1) if I upload this working program in the board, unplugging the USB and of course giving just the power supply through the jack on the breakout board it does not work anymore and stops on the message "preparing network connection...". But Intel Edison has an integrated wifi module and I really can't understand why it is not able to establish an internet connection anymore without the help of the USB connection with my laptop. What's wrong with it? how to boot and execute this program just with the power supply? This is the setup function() of my program, we don't reach the loop() one so I will not post it
void setup()
{
// ------ LCD IN ACTION ------ //
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// setting the color for the connection
lcd.setRGB(colorR, colorG, colorB);
lcd.print("preparing network connection...");
// scroll 40 positions (string length) to the left
// to move it offscreen left:
for (int positionCounter = 0; positionCounter < 40; positionCounter++)
{
// scroll one position left:
lcd.scrollDisplayLeft();
// wait a bit:
delay(350);
}
// ------ SERIAL CONNECTION ------ //
// opening the serial connection
// Serial.begin(9600); // initialize serial communication
// ------ SETTING I/O PINS ------ //
pinMode(potentiometer, INPUT); // angle sensor's pin for input.
pinMode(12, OUTPUT); // set the blue LED pin mode
pinMode(13, OUTPUT); // set the red LED pin mode
pinMode(pinLed, OUTPUT); // set the green LED pin mode
// ------ WIFI CONNECTION CONTROLS ------ //
// check for the presence of the wifi shield:
if (WiFi.status() == WL_NO_SHIELD)
{
// Serial.println("WiFi shield not present");
while(true); // don't continue
}
// check firmware version
String fv = WiFi.firmwareVersion();
// if( fv != "1.1.0" )
// Serial.println("Please upgrade the firmware");
// ------ WIFI CONNECTION ------ //
// attempt to connect to Wifi network:
while (status != WL_CONNECTED)
{
// Serial.print("Attempting to connect to Network named: ");
// Serial.println(ssid); // print the network name (SSID);
// connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 3 seconds for connection:
delay(3000);
}
server.begin(); // start the web server on port 70
printWifiStatus();
where
void printWifiStatus() {
// print the SSID of the network you're attached to:
// Serial.print("SSID: ");
// Serial.println(WiFi.SSID());
colorR = 255;
colorG = 180;
colorB = 0;
lcd.clear();
lcd.setRGB(colorR, colorG, colorB);
lcd.print(WiFi.SSID());
delay(3000);
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
// Serial.print("IP Address: ");
// Serial.println(ip);
colorR = 0;
colorG = 255;
colorB = 0;
lcd.setCursor(0, 1);
lcd.setRGB(colorR, colorG, colorB);
lcd.print(ip);
delay(3000);
/*
delay(5000);
colorR = 180;
colorG = 255;
colorB = 255;
lcd.setRGB(colorR, colorG, colorB);
lcd.noDisplay();
*/
// print the received signal strength:
long rssi = WiFi.RSSI();
// Serial.print("signal strength (RSSI):");
// Serial.print(rssi);
// Serial.println(" dBm");
// print where to go in a browser:
// Serial.print("To see this page in action, open a browser to http://");
// Serial.println(ip);
}
2) always about the execution of pre-loaded programs: if I load the default blink program of ArduinoIDE, unplug the USB and just give the power supply it works perfectly [this one is correctly self-booted, yes] but if I upload the same program with a Serial.begin() and a Serial.print("Arduino blinking") it doesn't work anymore without the USB connection to my laptop [this is why I commented the Serial stuff before]. Is it because the board is so smart to detect that in the first case the serial connection is not really happening?
3) last question about program storage: when I compile a program with the arduino IDE it gives me the percentage of memory used related to the available one for programs
Sketch is using 103.266 byte (1%) of program memory. The limit is 10.000.000 byte
but Intel Edison has a 4GB eMMC so why there are only 10MB available to programs? in which memory are the programs uploaded?
Thanks in advance to those who will try to help
Do you know how can I do to check where is it stored?
You can check your files on serial communication terminal. If you have possible directories that your file could be in, you can use linux commands like:
cd directory and ls
or even you can 'search' the file if you know the name. You may want to check this site.
or you can use SCP, FTP client programs like WinSCP to see the files on your Edison.
if I upload this working program in the board
Are you sure that your program is flashed into persistent memory ? I do not know this board. In most cases this kind of problems comes when your program is only transferred to RAM memory, but not stored in Flash.
Sketch is using 103.266 byte (1%) of program memory. The limit is
10.000.000 byte
10MB RAM, or Flash memory ?
As far as I understand you use Arduino + Edison ?
Which board 10MB limit corresponds to ? Sketch is using 103.266 byte: is it RAM or Flash ?
Try typing these commands in through putty
ifconfig usb0 down
ifconfig wlan0 down
ifconfig usb0 up
ifconfig wlan0 up
that might do it