I want to communicate with a SHT21 Sensor from a EK-TM4C1294XL Board.
But it seems that I2C communication is quite difficult with energia.
I used different setups with external Pullup, used the internal pullup and also no pullup. then i tried both I2C interfaces by setting Wire.setModule(0) or Wire.setModule(1) but in all cases the result is that either everything freezes in the Wire.endTransmission() function or i receive only bytes filled with 0.
I basically used this library: https://github.com/elechouse/SHT21_Arduino and modified the example script like this:
#include <Wire.h>
#include <SHT2x.h>
void setup()
{
Wire.setModule(1); // SCL = PN_5 (pin 49), SDA = PN_4 (Pin 50)
Wire.begin();
// optional use this:
// pinMode(PN_5, INPUT_PULLUP);
// pinMode(PN_4, INPUT_PULLUP);
Serial.begin(115200);
}
void loop()
{
Serial.print("Humidity(%RH): ");
Serial.print(SHT2x.GetHumidity());
Serial.print(" Temperature(C): ");
Serial.println(SHT2x.GetTemperature());
delay(1000);
}
There is a boosterpack containing the SHT21 as well, but i did not found any sample code for that... I did not managed yet to get the C stuff running on my linux machine, probably I2C is broken in the energia lib?
Edit: it seems that there is a bug in the library too. The timing must be precise and also 3 bytes are requested and only 2 read. when reading the last byte i do not get good values but at least the loop does not freeze.
Related
I am begginer on Arduino. I am student and this is my first homework.
Please, could someone explain to me how to understand the following codes. Which code is better? How do operators affect the executive speed? Below is the content.
"The task was to measure the speed of code execution depending on the programming technique used. The program code was designed to expose the high and low states to the D10 (PB2) port respectively without entering delays – as a result, we obtained a rectangular waveform with the maximum frequency for a given program recording method. Programs were written by putting all statements in void setup() omitting the void loop().
Preparation for the exercise consisted in connecting the Arduino Uno board to the USB port, starting the Arduino IDE environment and turning on the oscilloscope. The oscilloscope was used to observe the rectangular waveform generated from the D10 pin (PB2) and to measure its frequency."
Code of the first program:
const byte outPin = 10;
void setup() {
pinMode(outPin,OUTPUT);
while (1)
{
digitalWrite(outPin, HIGH);
digitalWrite(outPin, LOW);
}
Code of the second program:
const byte outPin = B00000100;
void setup() {
DDRB | = outPin;
while (1)
{
PORTB = B00000100;
PORTB = B11111011;
}
Third program code:
const byte outPin =10;
byte state =0;
void setup() {
pinMode(outPin,OUTPUT);
while (1)
{
digitalWrite(outPin, state);
state = !state;
}
Code of the fourth program:
#define _BV(n) (1<<n)
const byte outPin= B00000100;
byte state = _BV(2);
void setup()
{
DDRB|=outPin;
}
while (1){
PORTB |=state;
PORTB &=~state;
}
Code of the fifth program:
const byte outPin= B00000100;
void setup()
{
DDRB|=outPin;
while (1){
PORTB |=B00000100;
PORTB &=B11111011;}
}
As I said I am begginer on ARDUINO UNO. I cannot find any solution to explain exactly my homework.
Which code is better?
The first one, of course. Reasons:
Usually, it's fast enough.
The other ones are hardware specific and do not run on any Arduino, but just on atmega328P microcontrollers.
How do operators affect the executive speed?
It's the call to digitalWrite, which makes the difference, not some operators like ~ . You should look for an similarly hardware independent replacement to digitalWrite, which does the translation between Arduino pin number and hardware register only once at compile time.
BTW: your question is off topic here :)
I want to read data from AD7124-8 with arduino Due via SPI. I found several libraries, but i dont get anything back from my ADC modul. By using an Oscilloscope i made sure my Arduino sends data via MOSI, SCK and CS work aswell. Just the MISO dataline doesnt get me anything back.
I first used this library (https://github.com/NHBSystems/NHB_AD7124), but decided to use a much easier Code to just make sure everything is working fine. I tried to to talk to the communication register to get the ID of my device from the ID register. You can find the registers on page 39 of the datasheet :https://www.analog.com/en/products/ad7124-8.html .
Im sending 0x00 and 0x05 to get back the 0x14 which should be the correct ID. Just zeros arriving (shown by Osci).
I found a solution in a Forum, but im not sure about why it differs with the data sheet:
https://ez.analog.com/data_converters/precision_adcs/f/q-a/24046/ad7124-8-for-arduino-due
when i use it the code stops running at the Line: value[0] = SPI.transfer(0x00);
They send 0x40 at the beginning, too.
Here my simple Code:
#include <SPI.h>
// Physical Pins
const int csPin = 10;
int value[7] {0};
void setup() {
Serial.begin (9600);
pinMode(10,OUTPUT);
SPI.begin(10);
SPI.setClockDivider(10, 128);
SPI.setDataMode(SPI_MODE3);
}
void loop() {
digitalWrite(csPin, LOW);
//SPI.transfer(csPin, 0x00);
SPI.transfer(csPin,0x00,SPI_CONTINUE); //Tell Communication Register you are going to read ID register
SPI.transfer(csPin,0x05);
//SPI.transfer(csPin,0x00); //Get data from Communication Register
delay(1);
digitalWrite(csPin, HIGH);
delay(1);
Serial.print(value[0],HEX);
}
I hope someone can help me out.
Greetings
First of all, this may not related to your question, but you are using old SPI methods setClockDivider(), setDataMode(), and setBitOrder() that has been deprecated since 2014. It is recommend to use use transactional SPI APIs which I have some explanation here.
Secondly, according to datasheet page 85, to access the ID register, you send one-byte to specific which register that you need to communicate with. Your code send two bytes, 0x00 and 0x05, which is incorrect.
Furthermore, based on page 78 of the datasheet, in order to read a register, bit 6 need to be set to 1 for a read operation, and 0 for a write operation.
Try the following code:
#include <SPI.h>
#define READ_REGISTER 0B01000000 // bit 6 set to 1 for read operation
#define ID_REGISTER 0x05
const int csPin = 10;
void setup() {
Serial.begin (9600);
digitalWrite(csPin, HIGH); // set csPin to HIGH to prevent false trigger
pinMode(csPin,OUTPUT);
SPI.begin();
}
void loop() {
SPI.beginTransaction(SPISettings(84000000/128, MSBFIRST, SPI_MODE3));
digitalWrite(csPin, LOW);
SPI.transfer(READ_REGISTER | ID_REGISTER); // read register 5
uint8_t id = SPI.transfer(0x00); // get the id
digitalWrite(csPin, HIGH);
SPI.endTransaction();
Serial.print(id,HEX);
}
I use Amarino with SoftwareSerial (from here: http://www.double-oops.org/mini-blog/amarinowithsoftwareserial ) but I have a strange issue.
It seems that there are some strange behaviour in the MeetAndroid Library. In order to receive events I had to make this changes:
in init() I had to change
ack = 19;
with
ack = 226;
because this is the char I received from the phone at the end of a message
and in receive() I had to change
uint8_t lastByte;
with
char lastByte;
otherwise the
if(lastByte == ack)
won't be true ever
Does anyone have any idea why I had this problems? Why do i get another ack char and why is the if not working for char (ack) and uint8_t (lastByte)
This is my sketch:
/*
Receives Test Events from your phone.
After it gets a test message the led 13 will blink
for one second.
*/
#include <MeetAndroid.h>
#include <SoftwareSerial.h>
MeetAndroid meetAndroid(4, 2, 115200);
int onboardLed = 13;
void setup()
{
meetAndroid.registerFunction(testEvent, 'A');
pinMode(onboardLed, OUTPUT);
digitalWrite(onboardLed, HIGH);
}
void loop()
{
meetAndroid.receive(); // you need to keep this in your loop() to receive events
}
void testEvent(byte flag, byte numOfValues)
{
flushLed(300);
flushLed(300);
}
void flushLed(int time)
{
digitalWrite(onboardLed, LOW);
delay(time);
digitalWrite(onboardLed, HIGH);
delay(time);
}
I found the problem, it is baudrate related. When using software serial I have to use a lower baudrate (9600 for example), otherwise when receiving multiple characters at once it won't work. And since amarino library sends multiple library at once (signaling the start and the end of the message for example) it caused problems when using software serial on slower hardware (like the Arduino Uno used by me). Probably with better hardware (Arduino Mega) changing the baudrate is not necessary.
Example for changing the baudrate is available here:
Receiving multiple chars at once with Software Serial
Long answered short:
When using SoftwareSerial on slower hardware use a low baudrate (like 9600). Also make sure to set the bluetooth board work on the lower baudrate.
I just purchased Seeed's TFT Touch Shield 2.0 for Arduino, but I cannot seem to figure out how to access the SD card while maintaining the ability to draw to the screen. The tutorials and documentation are quite insubstantial (for me), and most questions on the product site seem to be directed to the same wiki page, which doesn't explain anything about the SD interface, other than what example file draws bitmaps from the card.
I've used the SD interface with the Ethernet Shield before, but it's been a long time since then, so I can't quite remember the ins and outs. From my old code, it seems that, for normal usage of the SD library, you simply do:
#include <SD.h>
void setup()
{
pinMode(4, OUTPUT);
if (!SD.begin(4))
{
//Fail
}
... //Open file, read, etc.
}
To use the TFT screen normally (with the exception of drawing bitmaps), you do as such:
#include <SD.h>
#include <TFTv2.h>
#include <SPI.h>
void setup()
{
TFT_BL_ON; //Enable Backlight
Tft.TFTinit(); //Initialize TFT Screen
Tft.drawCircle(100, 100, 30,YELLOW); //Draw
}
In the provided example program on the wiki page for drawing bitmaps from the SD card, the setup code looks like this:
#include <SD.h>
#include <TFTv2.h>
#include <SPI.h>
#define chipSelect 4
Sd2Card card;
void setup()
{
pinMode(11,INPUT);
pinMode(12,INPUT);
pinMode(13,INPUT);
TFT_CS_HIGH;
pinMode(chipSelect,OUTPUT);
digitalWrite(chipSelect,HIGH);
Serial.begin(38400);
SPI.begin();
Tft.TFTinit();
//SPI.setClockDivider(SPI_CLOCK_DIV4);
//SDcard_info();
/**/
DDRB |= 0x04;
card.init(SPI_FULL_SPEED,chipSelect);
if(!SD.begin(chipSelect))//SPI_QUARTER_SPEED,
{ //53 is used as chip select pin
Serial.println("failed!");
while(1);
}
Serial.println("SD OK!");
Tft.setCol(0,239);
Tft.setPage(0,319);
Tft.sendCMD(0x2c);//start to write to display ram
TFT_BL_ON;
}
In loop() bitmaps are sequentially opened with SD.open(), drawn, and then closed with SD.close().
What I assume is happening is that pins 11 through 13 are set to input for some SPI-related reason, the TFT chip select 'enabled' mode is set to HIGH, and then the screen is subsequently enabled. Serial moniter is started, followed by SPI, and then the TFT. After those things happen, it does something unknown to me, starts the card, and then uses the standard card initialization method. It finishes up by preparing to draw the bitmaps and sends this 'command 0x2c', which is used frequently in the underlying libraries to "start to write to display ram".
The problem is that I have tried initializing the TFT and SD card using this code, and then attempted to draw graphics as shown in my second example, but this did not work. I need to be able to read bytes from the SD card, and then be able to draw simple graphics on-screen, and repeat.
So my question is: Is anyone who has used this shield before or has experience with this able to explain how one should go about writing the code to allow usage of both the SD card and screen or how the initialization and SPI processes work to make this possible?
Thanks for your answers in advance!
(Also, if this is not the correct SE site for this question, please feel free to migrate it accordingly.)
The solution to this problem is quite simple actually, and I must have been doing something wrong when I had combined the source files before.
The initialization code looks like this:
#include <SD.h>
#include <TFTv2.h>
#include <SPI.h>
Sd2Card card;
void setup()
{
pinMode(11, INPUT); //Pin mode changes; not sure what for
pinMode(12, INPUT);
pinMode(13, INPUT);
TFT_CS_HIGH; //Something with chipselect and the TFT
pinMode(4, OUTPUT); //Set chipselect pin to OUTPUT
digitalWrite(4, HIGH); //Set chipselect mode
SPI.begin(); //Start SPI
Tft.TFTinit(); //Initialize the TFT
TFT_BL_ON; //Turn on the TFT Backlight
Serial.begin(9600); //Start serial output
DDRB |= 0x04; //Some sort of processor IO port?
if(!SD.begin(4)) //Start the SD card
{
while(true) { } //Fail
}
}
It is basically the bitmap initialization code, with the extra TFT commands at the end left out. After this, both the screen and the SD card are usable, as was desired.
Does anyone have experience with the MPL3115A2 Freescale I2C pressure sensor?
I need to use it in a project concerning Arduino UNO r3, but I can't get communication between them correctly. Here is my code:
#include <Wire.h>
void setup(){
Serial.begin(9600);
/*Start communication */
Wire.begin();
// Put sensor as in Standby mode
Wire.beginTransmission((byte)0x60); //0x60 is sensor address
Wire.write((byte)0x26); //ctrl_reg
Wire.write((byte)0x00); //reset_reg
Wire.endTransmission();
delay(10);
// start sensor as Barometer Active
Wire.beginTransmission((byte)0x60);
Wire.write((byte)0x26); //ctrl_reg
Wire.write((byte)0x01); //start sensor as barometer
Wire.endTransmission();
delay(10);
}
void getdata(byte *a, byte *b, byte *c){
Wire.beginTransmission(0x60);
Wire.write((byte)0x01); // Data_PMSB_reg address
Wire.endTransmission(); //Stop transmission
Wire.requestFrom(0x60, 3); // "please send me the contents of your first three registers"
while(Wire.available()==0);
*a = Wire.read(); // first received byte stored here
*b = Wire.read(); // second received byte stored here
*c = Wire.read(); // third received byte stored here
}
void loop(){
byte aa,bb,cc;
getdata(&aa,&bb,&cc);
Serial.println(aa,HEX); //print aa for example
Serial.println(bb,HEX); //print bb for example
Serial.println(cc,HEX); //print cc for example
delay(5000);
}
The data I receive is : 05FB9 (for example). When I change the register address (see Wire.write((byte)0x01); // Data_PMSB_reg address), I expect the data to change, but it doesn't! Can you explain this to me?
You can find the documentation and datasheets on the NXP website.
I can't properly understand how they communicate with each other. I got communication between Arduino and some other I2C sensors with same communication protocol without any problem.
Your problem is likely due to the fact that the Freescale part requires Repeated-Start I2C communication to do reads. The original Arduino two-wire library (TWI library used by Wire), did not support Repeated-Start.
I know this because I had to rewrite TWI for one of my projects to support Repeated-Start (interrupt driven, both Master and Slave). Unfortunately I've never gotten around to uploading my code, but someone else did essentially the same thing here (at least for Master which is what you need):
http://dsscircuits.com/articles/arduino-i2c-master-library.html
Lose the Wire library and use their I2C library instead.