Propeller Activity Board for I2C interface "Line follow sensor" question
王柏鈞
Posts: 21
Hello everyone, I am a university student from TW
I want to using propeller Activity Board to follow the Line
I use SimpleIDE to writing my project
But I'm not really understand how to read I2C sensor
////////////////////////this is my code////////////////////////////////////////////////////
#include "i2ceasy.h"
#include "simplei2c.h"
#include <math.h>
int x=0;
int main()
{
while (1)
{
i2c__init(3, 2); // SCL pin, SDA pin
x=i2c__read(0x3E);
print("x = %d\n", x);
pause(500);
}
}
////////////////////////this is my code////////////////////////////////////////////////////
And I using the sparkfun line follower array
I think it have singel to my board,but it can't read the sensor detect
can someone help me?
I want to using propeller Activity Board to follow the Line
I use SimpleIDE to writing my project
But I'm not really understand how to read I2C sensor
////////////////////////this is my code////////////////////////////////////////////////////
#include "i2ceasy.h"
#include "simplei2c.h"
#include <math.h>
int x=0;
int main()
{
while (1)
{
i2c__init(3, 2); // SCL pin, SDA pin
x=i2c__read(0x3E);
print("x = %d\n", x);
pause(500);
}
}
////////////////////////this is my code////////////////////////////////////////////////////
And I using the sparkfun line follower array
I think it have singel to my board,but it can't read the sensor detect
can someone help me?
Comments
http://learn.parallax.com/propeller-c-simple-protocols/diy-i2c
But it is hardware tutorial , I want to know about how to work with software.
And in that web , it say I can use "ee_putByte, ee_getByte, ee_putInt, ee_getInt, ee_putFloat32, ee_getFloat32, ee_putStr, and ee_getStr." to quick way saved data .Can I using that to saved my sensor data?
To get to the next page look at the bottom of the page I linked to you. You will see what I show below between 3 horizontal lines:
Bottom right is the link to the next page. Click on "EEPROM Test Code" and you will see a whole page on how to use the I2C library function. There will be two more pages after that.
I see that , I think that is helpful,but I have some question for it.
Isn't "i2cAddr" sensor address? or the 0b1010000 just the EEPROM's address? It seen like just the EEPROM's address.
If I want to add my sensor,is that code right?
"i2c_in(eeSensor, 0x3E, memAddr, 2, (char*)&val, 8 );"
"eeSensor"is a new I2C bus name,"0x3E"is my sensor I2C address.
memAddr is the device's internal address followed by how many bytes memAddr is long. You put 2 after memAddr, meaning that memAddr is 16 bits wide. Does your device have that many internal addressable locations? I2C expander chips do not. You probably want to use 1.
(char*&val,8); is something that you copied from the example in the last page dealing with reconstructing a 16-bit word from two 8-bit bytes from an eeprom. Don't do that! Instead, use the array name you have established to point to the data byte(s) to store the data that was read from the device, followed by how many bytes you want to read. inByte should be a char array, for example; To properly read the I2C bus with a specific device on that bus is going to require you to dig into the device data sheet and find out what the internal addresses are. I encourage you to try the tutorials on your Propeller Activity board and get comfortable with the way the I2C Library works. I use it with many devices such as RTC, expanders, EEPROM, etc.
"memaddr" is my sensor memory address,right ? But I don't know my sensor memory address.
I read "Did you know?" page , but English is not mine native language , so I can't really understand what it mean.
I just know Propeller board's EEPROM addresses is 0 to 32767,how did that know?
I'm so sorry about asking you so many idiot questions.
Is this the device you are trying to use?
yes, I try for this sensor.
And I look the datasheet for SX1509, It say "0x3E" should be "0111110" , not "0011111",isn't it?
I found a library for propeller , it's name "i2ceasy.h",did you use it before?
For someone who has very little knowledge with I2C programming, learning with an SX1509 will be a very difficult task.
I am not familiar with 12ceasy.h, cannot help you with that.
I know 0 for write,1 for read,but I don't know how to put it in program.
/////////////////////////////////////////////////////////////////////////////////////////////
#include "simpletools.h" // Include simpletools header
int x;
char inByte[2];
i2c *eeSensor;
int memAddr = 32768;
int main() // Main function
{
while(1)
{
eeSensor = i2c_newbus(4,3,0);
i2c_in(eeSensor, 0b1111100, memAddr, 1, inByte, 2);
print("val = %d \n",inByte);
pause(500);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////
It will running for inByte=9527, can you help me to modify it?
I think my memAddr is the problem for it , isn't it?
or should I use "EEPROM" for reading the "inByte"?
Several problems with your code;
The statement "eeSensor = i2c_newbus(4,3,0);" should be placed before the while(1) loop. You don't want to constantly run the newbus statement hundreds or thousands of times. Once will do it until you close the bus.
Next is the device address. Remember, this I2C library will take your 7-bit address and shift it left once. The address you have given has a 1 bit in the left -most position which will be lost - not a good thing! Another way of converting an 8-bit I2C address to 7-bit is to simply divide it by two. 0x3E / 2 = 0x1F or b00011111. Now, starting from the right, or LSB position, count off 7 bits and you should have 0b0011111.
Do not concern yourself with the read/write bit. The library will take care of that. After it shifts the 7-bit address left once it will insert the proper bit into the LSB position, depending on the operation.
memAddr This parameter is telling the I2C library the location (or address) of the register or memory byte that is inside the slave device. This is where you have to look at the datasheet for the address of the location you want to read. You have indicated a memAddr of 32768. You probably got this number from the tutorial that was accessing the 2nd half of a 64KB EEPROM. Again, the information is in the datasheet. The number following memAddr is the number of 8-bit bytes that memAddr is made up of. If your device has 255 or less locations memAddr will be 1 byte. If the highest address is between 256 and 65565 then memAddr will have 2 bytes, and so on.
It looks like you are making some progress. Just remember to refer to the device data sheet for the addresses of the locations you want to read. In most cases, when a device has multiple addresses it will auto-increment its location pointer so that the next read or write command will read or write the next location.
Why can I2C address divide by two? When I divide it by two , the address will be 0x1F, can it find the right address?
I put "eeSensor = i2c_newbus(4,3,0);" before "while(1)"(I am so idiot for put it in while) , inByte will be "9520".It look like it doesn't read the sensor.
So the memAddr is the memory byte of the register?I just wanting to read 255 to my device, so the memAddr will be 1 byte,right?
Yes,I am making some progress for robot race, it can use I/O pin for other sensor to do that,but that race should need colorPal、Ultrasound and line following sensor, so I want to try the I2C sensor for not using so many I/O pin.
In the SX1509 data sheet on pages 30 - 35 is the listing and description of the device internal registers. The highest address is 0x7F so memAddr should never be greater than 0x7F.
Which location are you trying to read?
If, for example, you wish to read location 0x0F ( RegDirA) then your code might look like the following: This should result in a display of 255 repeating 2 times per second.
I try this code and change the SX1509 register address for other address,but it still return inByte=9720.
Should I use other I2C sensor to text it work or not?
I was finding some data for I2C , but not find useful data for this progress.
The code is like the code you post.
I don't pull up resistors because when I pull 1k resistor it will not enough to work(I put it for the VIN),and I try put 1k and 220 resistor for two I2C line, it still return 9720.
The only item in the code I did not include is the line but you would get compiler errors if that was missing.
Do you have other types of I2C devices like an EEPROM that you can try to make sure the code is working?
I was include that library on the top,so it wasn't errors for compiler.
The powering I was use 5 Volts for board.
I was using for arduino before,but I don't use any resistors and it can work.
Sensor board
5v->5v
GND->GND
SDA->P3
SCL->P4
All without any resistors
Do you have a Voltmeter to verify that P3 and P4 are at 3.3 Volts? It is best that you remark out the i2c_in... statement so there is no activity on the bus.
I was able to establish I2C communications for Sparkfun board on the Arduino,but the Sparkfun company have provide a library for this sensor,it let this sensor easy to ues for Arduino.
And I try the example, it can work on Arduino.
P3 and P4 are at 1.2Volts,but I see everyone put the I2C pin for P2 and P3 can work, I also try this is,but it's the same promble.
Several posts up your reply to the code I provided was;
"I try this code and change the SX1509 register address for other address,but it still return inByte=9720."
What did you change the SX1509 register address to?
I don't have any other I2C slave device besides the SX1509.
I change the register address in the code "0x0F" for the other address on page 30~35.Not change the SX1509 register address.
I was reading the i2c_in statement before,but I see some people use P3&P2 for i2c_in in their progress.So I think it is fine to use P3&P4.
And I test the arduino A4&A5 for I2C ping, it is 4.5v,I think maybe is the voltage promble.
You say "With that one half second delay between readings the meter should be show a much closer to 3 Volts or slightly more" , what's it mean?Isn't change delay to delay(250) or lower?
What I am referring to is the I2C bus for the propeller must be pulled up to 3.3 volts. Active devices on the bus pull the lines to zero volts during data transfer. The devices only pull down, the pull up resistors are required so that when the device stops pulling the line down the voltage on that line goes back to 3.3 volts.
My concern here is that you have used this Sparkfun board on an Arduino, which runs on 5 volts. The Sparkfun board has several jumpers on it that let you set the pull up to none, 3.3 Volts, or 5 Volts. If it is set to none and you now try to run it on the Propeller Activity board without any pull up resistors, the I2C will not work.
My reference to the half second delay was just me thinking out loud that even if you did not disable the i2c_in... statement the amount of activity on the bus is quite low and as a result your meter should see a voltage much closer to 3.3 Volts. The 1.2 Volt reading you gave me earlier is less than half the voltage the propeller runs on.
I'm just trying to get you to provide a clean, quiet bus voltage reading to make sure that it is being pulled up to 3.3 volts. If you are not sure on how to disable that statement, just place // in front of it to make it a comment. Then compile and download the program, and then check the voltage.
I'm so sorry for that,I change a voltmeter and I detect again P3 and P4, the voltages is almost closer 3.3v. And it also return 9720 for me.So it is not the voltages promble.
http://learn.parallax.com/propeller-c-simple-protocols/diy-i2c
I test it and it is work.The screen show "testSr =abcdefg".
A0 and A1 jumpers are in the '0' position back of the board.I don't change it and also use the 3E address for Arduino is work.