Hi Harry
I connected a sht15 to the gumstix on the gumstix port in the robostix.
http://docwiki.gumstix.org/index.php/Robostix_I/O_pins#Gumstix.28aka_console_or_FFUART.29
GPIO 39 and 34.
So I change:
#define SHT_CLK 39//65
#define SHT_VDD 66
#define SHT_GND 67
#define SHT_DTA 34//68
And I commented the GND VDD part in the main function:
// gpio_function(SHT_GND, GPIO);
gpio_function(SHT_DTA, GPIO);
gpio_function(SHT_CLK, GPIO);
// gpio_function(SHT_VDD, GPIO);
/* Then set the direction */
// gpio_direction(SHT_GND, OUT);
gpio_direction(SHT_DTA, OUT);
gpio_direction(SHT_CLK, OUT);
// gpio_direction(SHT_VDD, OUT);
// gpio_clear(SHT_GND);
// gpio_set(SHT_VDD);
gpio_set(SHT_DTA);
gpio_set(SHT_CLK);
The I compiled and run and I got error 4:
root@...:~$ rayabot-sht15
temp: 65280 humi: 65280
Got error 4
temp: 65280 humi: 65280
Got error 4
temp: 65280 humi: 65280
Got error 4
temp: 65280 humi: 65280
Got error 4
If I disconect the sensor and run again the program it returns the same error.
So I am guesing that the read and write of the GPIO are not working...
I put in the main function:
while(1) {
if(read_bit()) printf("1\n");
else printf("0\n");
delay(1000);
}
And connected the data pin(34) to gnd and and then to vdd manualy.
But I get 1 on the screen all the time. :/
Do I have to change something else to read and write on the 39 and 34 GPIO?
How can I check I am not using the FFUART(GPIO 39 and 34) with
something else on the gumstix?
Thanks for the code. It is very usefull.
On Thu, Mar 27, 2008 at 6:44 AM, Harry J Mason <hjm03r@...> wrote:
> On Wed, 26 Mar 2008, Hanguang wrote:
>
>> Harry Mason wrote:
>>> I'm using the SMT71 from Sensirion, which is digital but not i2c so you
>>> would need GPIO but not an ADC. It has a simple bit banging protocol and
>>> comes with sample code which is easy to port to the Gumstix.
>>
>> I also found someone else on internet talked about SMT71. Do you have any
>> good tutorial or article shows more detail? Or just simiply tell me the
>> procedure you did with you stuff.
>
> The data sheet and technical notes are good, and available at
> http://www.sensirion.com/en/01_humidity_sensors/05_humidity_sensor_sht71.htm
>
> It does not use i2c but the connections are similar. You need two GPIO pins
> for communication, and I'm also using GPIO for power as it makes the wiring
> convenient. The data line needs a pullup resistor (around 10k) or it doesn't
> work.
>
> To drive it from Linux I combined their sample code and a user space GPIO
> library I found somewhere in the Gumstix documentation. Halfway down the
> code there are constants (SHT_CLK etc.) defining which GPIO pins provide power,
> data, and clock; change these to match your setup.
>
> I'm using the SHT7x which has pin connectors; these are intensely frustrating
> to solder. Be quick and careful or you'll affect the accuracy. Also note that
> the pinouts of the SHT1x and SHT7x are different - make sure you're reading the
> right one in the data sheet.
>
> Harry
>
> -- 8< -- code follows -- 8< --
> #include <stdio.h>
> #include <time.h>
> #include <stdio.h>
> #include <unistd.h>
> #include <stdlib.h>
> #include <string.h>
> #include <sys/mman.h>
> #include <sys/types.h>
> #include <sys/stat.h>
> #include <fcntl.h>
> #include <ctype.h>
> #define MAP_SIZE 4096
> #define MAP_MASK ( MAP_SIZE - 1 )
> #define GPLR0 0x40E00000
> #define GPLR1 0x40E00004
> #define GPLR2 0x40E00008
> #define GPDR0 0x40E0000C
> #define GPDR1 0x40E00010
> #define GPDR2 0x40E00014
> #define GPSR0 0x40E00018
> #define GPSR1 0x40E0001C
> #define GPSR2 0x40E00020
> #define GPCR0 0x40E00024
> #define GPCR1 0x40E00028
> #define GPCR2 0x40E0002C
> #define GAFR0_L 0x40E00054
> #define GAFR0_U 0x40E00058
> #define GAFR1_L 0x40E0005C
> #define GAFR1_U 0x40E00060
> #define GAFR2_L 0x40E00064
> #define GAFR2_U 0x40E00068
>
> #define IN 250
> #define OUT 251
> #define GPIO 0
> #define AF0 0
> #define AF1 1
> #define AF2 2
> #define AF3 3
> #define SET 252
> #define CLEAR 253
>
> typedef unsigned int u32;
>
> void *map, *regaddr;
> static void putmem(u32 addr, u32 val)
> {
> regaddr = map + (addr & MAP_MASK);
> *(u32*) regaddr = val;
> }
> static int getmem(u32 addr)
> {
> u32 val;
>
> regaddr = map + (addr & MAP_MASK);
> val = *(u32*) regaddr;
> return val;
> }
> void gpio_set(u32 gpio)
> {
> u32 pos;
> u32 bit = 1;
>
> pos = gpio / 32;
> bit <<= gpio % 32;
> putmem(GPSR0 + (pos * 4), bit);
> }
> void gpio_clear(u32 gpio)
> {
> u32 pos;
> u32 bit = 1;
>
> pos = gpio / 32;
> bit <<= gpio % 32;
> putmem(GPCR0 + (pos * 4), bit);
> }
> u32 gpio_status(u32 gpio)
> {
> u32 pos;
> u32 bit = 1;
> u32 data;
>
> pos = gpio / 32;
> bit <<= gpio % 32;
> data = getmem(GPLR0 + (pos * 4));
> data &= bit;
> if (data == 0)
> return(0);
> else
> return(1);
> }
> void gpio_direction(u32 gpio, u32 dir)
> {
> u32 pos;
> u32 bit = 1;
> u32 data;
>
> pos = gpio / 32;
> bit <<= gpio % 32;
> data = getmem(GPDR0 + (pos * 4));
> data &= ~bit;
> if (dir == OUT)
> data |= bit;
> putmem(GPDR0 + (pos * 4), data);
> }
> void gpio_function(u32 gpio, u32 fun)
> {
> u32 pos;
> u32 bit = 3;
> u32 data;
>
> pos = gpio / 16;
> bit <<= (gpio % 16) * 2;
> fun <<= (gpio % 16) * 2;
> data = getmem(GAFR0_L + (pos * 4));
> data &= ~bit;
> data |= fun;
> putmem(GAFR0_L + (pos * 4), data);
> }
> u32 gpio(u32 dir, u32 set, u32 reg)
> {
> if ((dir != IN) & (dir != OUT)){
> printf("ERROR: must specify a valid direction\n");
> return(1);
> }
> if ((set != SET) & (set != CLEAR)){
> printf("ERROR: must specify a valid level\n");
> return(1);
> }
> if (reg > 84){
> printf("ERROR: not a valid register -->%d\n", reg);
> return(1);
> }
> gpio_function(reg, GPIO);
> gpio_direction(reg, dir);
> if (dir == OUT){
> if (set == SET)
> gpio_set(reg);
> else
> gpio_clear(reg);
> }
> return(0);
> }
>
> inline void delay ( long d ) {
> struct timespec ts;
> ts.tv_sec = 0;
> ts.tv_nsec = d * 1000;
> nanosleep(&ts, NULL);
> }
>
> /*
> * pin func GPIO
> * 1 CLK 82
> * 2 VDD 81
> * 3 GND 59
> * 4 DTA 60
> */
>
> #define SHT_CLK 65
> #define SHT_VDD 66
> #define SHT_GND 67
> #define SHT_DTA 68
>
> #define noACK 0
> #define ACK 1
> #define CMD_REG_W 0x06
> #define CMD_REG_R 0x07
> #define CMD_TEMP 0x03
> #define CMD_HUMI 0x05
> #define CMD_RESET 0x1e
>
>
> void write_bit(unsigned char bit) {
> if (bit) {
> /* We should only drive low; pullup should handle driving high.
> * Therefore writing 1 is the same as reading. */
> gpio_direction(SHT_DTA, IN);
> gpio_set(SHT_DTA);
> } else {
> gpio_clear(SHT_DTA);
> gpio_direction(SHT_DTA, OUT);
> }
> }
> unsigned char read_bit(void) {
> gpio_direction(SHT_DTA, IN);
> return gpio_status(SHT_DTA);
> }
> inline void clock_high(void) {
> gpio_set(SHT_CLK);
> }
> inline void clock_low(void) {
> gpio_clear(SHT_CLK);
> }
>
> unsigned char write_byte(unsigned char value) {
> unsigned char i, error = 0;
> for (i = 0x80; i > 0; i /= 2) {
> write_bit(i & value);
> clock_high();
> delay(5);
> clock_low();
> }
> write_bit(1);
> clock_high();
> error = read_bit();
> clock_low();
> return error;
> }
>
> char read_byte(unsigned char ack) {
> unsigned char i, val = 0;
> write_bit(1);
> for (i=0x80; i > 0; i /= 2) {
> clock_high();
> if (read_bit()) { val = (val | i); }
> clock_low();
> }
> write_bit(!ack);
> clock_high();
> delay(5);
> clock_low();
> write_bit(1);
> return val;
> }
>
> void transstart(void) {
> write_bit(1);
> clock_low();
> delay(1);
> clock_high();
> delay(1);
> write_bit(0);
> delay(1);
> clock_low();
> delay(5);
> clock_high();
> delay(1);
> write_bit(1);
> delay(1);
> clock_low();
> }
>
> void connectionreset(void) {
> unsigned char i;
> write_bit(1);
> clock_low();
> for (i = 0; i < 9; ++i) {
> clock_high();
> delay(1);
> clock_low();
> delay(1);
> }
> transstart();
> }
>
> char softreset(void) {
> unsigned char error = 0;
> connectionreset();
> error += write_byte(CMD_RESET);
> return error;
> }
>
> char read_statusreg(unsigned char *p_value, unsigned char *p_checksum) {
> unsigned char error = 0;
> transstart();
> error = write_byte(CMD_REG_R);
> *p_value = read_byte(ACK);
> *p_checksum = read_byte(noACK);
> return error;
> }
>
> char write_statusreg(unsigned char *p_value) {
> unsigned char error = 0;
> transstart();
> error += write_byte(CMD_REG_W);
> error += write_byte(*p_value);
> return error;
> }
>
> char measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode) {
>
> unsigned char error = 0;
> unsigned int i;
>
>
> transstart();
> switch(mode) {
> case CMD_TEMP: error += write_byte(CMD_TEMP); break;
> case CMD_HUMI: error += write_byte(CMD_HUMI); break;
> default : break;
> }
> for (i = 0; i < 100; ++i) {
> if (read_bit() == 0) break;
> delay(10);
> }
> if (read_bit()) {
> error += 1;
> }
>
> // endian?
> *(p_value+1) = read_byte(ACK);
> *(p_value) = read_byte(ACK);
> *p_checksum = read_byte(noACK);
> return error;
> }
>
> //----------------------------------------------------------------------------------------
> void calc_sth11(float *p_humidity ,float *p_temperature)
> //----------------------------------------------------------------------------------------
> // calculates temperature [ C] and humidity [%RH]
> // input : humi [Ticks] (12 bit)
> // temp [Ticks] (14 bit)
> // output: humi [%RH]
> // temp [ C]
> { const float C1=-4.0; // for 12 Bit
> const float C2= 0.0405; // for 12 Bit
> const float C3=-0.0000028; // for 12 Bit
> const float T1=0.01; // for 14 Bit @ 5V
> const float T2=0.00008; // for 14 Bit @ 5V
> float rh=*p_humidity; // rh: Humidity [Ticks] 12 Bit
> float t=*p_temperature; // t: Temperature [Ticks] 14 Bit
> float rh_lin; // rh_lin: Humidity linear
> float rh_true; // rh_true: Temperature compensated humidity
> float t_C; // t_C : Temperature [ C]
> t_C=t*0.01 - 40; //calc. Temperature from ticks to [ C]
> rh_lin=C3*rh*rh + C2*rh + C1; //calc. Humidity from ticks to [%RH]
> rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //calc. Temperature compensated humidity [%RH]
> if(rh_true>100)rh_true=100; //cut if the value is outside of
> if(rh_true<0.1)rh_true=0.1; //the physical possible range
> *p_temperature=t_C; //return temperature [ C]
> *p_humidity=rh_true; //return humidity[%RH]
> }
>
>
>
>
>
>
>
>
> int main( int argc, char **argv )
> {
>
> int temp_i = 0, humi_i = 0;
> float temp_f = 0, humi_f = 0;
> unsigned char error, checksum;
>
>
> int fd;
> fd = open("/dev/mem", O_RDWR | O_SYNC);
> if (fd<0) {
> perror("open(\"/dev/mem\")");
> exit(1);
> }
> map = mmap(0,
> MAP_SIZE,
> PROT_READ | PROT_WRITE,
> MAP_SHARED,
> fd,
> 0x40E00000 & ~MAP_MASK
> );
> if (map == (void*)-1 ) {
> perror("mmap()");
> exit(1);
> }
>
> gpio_function(SHT_GND, GPIO);
> gpio_function(SHT_DTA, GPIO);
> gpio_function(SHT_CLK, GPIO);
> gpio_function(SHT_VDD, GPIO);
>
> /* Then set the direction */
> gpio_direction(SHT_GND, OUT);
> gpio_direction(SHT_DTA, OUT);
> gpio_direction(SHT_CLK, OUT);
> gpio_direction(SHT_VDD, OUT);
>
> gpio_clear(SHT_GND);
> gpio_set(SHT_VDD);
> gpio_set(SHT_DTA);
> gpio_set(SHT_CLK);
>
> delay(10);
>
> connectionreset();
> delay(10);
>
> while (1) {
> error = 0;
> error += measure((unsigned char *)&temp_i, &checksum, CMD_TEMP);
> error += measure((unsigned char *)&humi_i, &checksum, CMD_HUMI);
> printf("temp: %d humi: %d\n", temp_i, humi_i);
> if (error != 0) {
> connectionreset();
> fprintf(stderr, "Got error %d\n", error);
> } else {
> humi_f = humi_i;
> temp_f = temp_i;
> calc_sth11(&humi_f, &temp_f);
>
> printf("temp: %5.1fC humi: %5.1f%%\n", temp_f, humi_f);
> }
>
> delay(1000);
> }
>
> munmap(0,MAP_SIZE);
> return 0;
> }
>
> -------------------------------------------------------------------------
> Check out the new SourceForge.net Marketplace.
> It's the best place to buy or sell services for
> just about anything Open Source.
> http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
> _______________________________________________
> gumstix-users mailing list
> gumstix-users@...
> https://lists.sourceforge.net/lists/listinfo/gumstix-users
>
--
Linus Casassa
Estudiante Ingeniería Civil Electrónica
Fono: 56-9-97776941
|