soloforce 发表于 2013-11-19 16:09:26

Cubieboard1显示DS18B20温度信息到LED

本帖最后由 soloforce 于 2013-11-19 17:10 编辑

Cubieboard1的内核已经支持w1温度传感器DS18B20 (依赖的内核选项和模块包括dallas's 1-wire support, gpio_sunxi, w1_sunxi, w1_gpio, w1_slave_therm )。 下图的DIY是在8位8段LED显示模块上同时显示当前时间和气温的实验。



jarry大侠在很久前的帖子(http://forum.cubietech.com/forum.php?mod=viewthread&tid=474)中介绍了DS18B20在cubieboard1上的使用,现在已经不需要打补丁或者另外编译内核模块了。只要按内核配置的说明改好script.bin即可:

本例中的script.fex相关设置如下:

gpio_used = 1
gpio_num = 31
...
gpio_pin_28 = port:PB10<0><default><default><0>
gpio_pin_29 = port:PB11<1><default><default><default>
gpio_pin_30 = port:PB13<1><default><default><default>
gpio_pin_31 = port:PH07<1><default><default><default>


gpio = 28

最后是本例的C代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <signal.h>
#include <pthread.h>
#include "gpio_lib.h"

#define LSBFIRST 0
#define MSBFIRST 1
#defineDISPBUF_LEN 8

typedef unsigned char byte;

// w1-thermal(DS18B20) device file, change it in your case.
const char* DS18B20_DEVICE="/sys/bus/w1/devices/28-000004f0230d/w1_slave";

/*
* 74HC595 relative stuff
*/
// Cubieboard pin connected to ST_CP of 74HC595 (RCK)
unsigned int latchPin = SUNXI_GPB(11);
// Cubieboard pin connected to SH_CP of 74HC595 (SCK)
unsigned int clockPin = SUNXI_GPB(13);
// Cubieboard pin connected to DS of 74HC595 (DIN)
unsigned int dataPin = SUNXI_GPH(7);

/*
* Display relative stuff
*/
// Digits: "0,1,2,....,9" for common anode 8-segment-LED
unsigned int digit_tab[] = { 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92,
                        0x82, 0xf8, 0x80, 0x90};
// Digits with a 'dot' at the right-bottom corner
unsigned int digitdot_tab[] = { 0xc0&0x7f, 0xf9&0x7f, 0xa4&0x7f,
                        0xb0&0x7f, 0x99&0x7f, 0x92&0x7f, 0x82&0x7f,
                        0xf8&0x7f, 0x80&0x7f, 0x90&0x7f};
// Symbols: 'clear', 'dot', '-'
unsigned int symbol_tab[]={ 0xff, 0x7f, 0xbf};
// LED display buffer
static char dispbuf;


/**
* Set Cubieboard's GPIO port-D pin I/O mode: INPUT/OUTPUT
*/
void pinMode(unsigned int pin, unsigned int io_mode)
{
    if (SETUP_OK != sunxi_gpio_set_cfgpin(pin, io_mode))
    {
      printf("Failed to config GPIO pin\n");
    }
}

/**
* Set Cubieboard's GPIO port-D pin value(LOW/HIGH)
*/
void digitalWrite(int pin, int hl)
{
    if (sunxi_gpio_output(pin, hl))
    {
      printf("Failed to set GPIO pin value\n");
    }
}

/**
* Arduino shiftOut:
* https://github.com/arduino/Arduino/blob/master/hardware/arduino/cores/arduino/wiring_shift.c
*/
void shiftOut(unsigned int dataPin, unsigned int clockPin, int bitOrder, byte val)
{
    byte i;
    for (i = 0; i < 8; i++)
    {
      if (bitOrder == LSBFIRST)
            digitalWrite(dataPin, ! !(val & (1 << i)));
      else
            digitalWrite(dataPin, ! !(val & (1 << (7 - i))));

      digitalWrite(clockPin, HIGH);
      digitalWrite(clockPin, LOW);
    }
}

/**
* Initialize the GPIO & relative pins
*/
void init_gpio()
{
    if (SETUP_OK != sunxi_gpio_init())
    {
      printf("Failed to initialize GPIO\n");
    }
    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
}

/**
* Get current temperature from the w1-thermal device
*/
void get_temperature(char* tempbuf, int len)
{
    FILE* fp=fopen(DS18B20_DEVICE,"r");
    char* line=NULL;
    char* temperature_tok=NULL;
    int temperature=0;
   
    int n;
    if(!fp){
      fprintf(stderr,"Failed to open device(%s) file!\n", DS18B20_DEVICE);
      return;
    }

    // skip the first line
    getline(&line, &n, fp);
    free(line);
    line=NULL;

    // get the temperature line
    getline(&line, &n, fp);
    strtok(line,"=");
    temperature_tok=strtok(NULL,"\n");
   
    strncpy(tempbuf, temperature_tok, len);

    free(line);
    fclose(fp);
}

/**
* Thread of filling the time infomation into display buffer
*/
void* time_to_dispbuf()
{
    time_t timep;
    struct tm *p;
    char timebuf;
    int interval=1; // in seconds

    while(1){
      // get localtime
      time(&timep);
      p = localtime(&timep);
      sprintf(timebuf, "%02d%02d", p->tm_hour, p->tm_min);

      dispbuf=digit_tab - '0'];
      dispbuf=digitdot_tab - '0'];
      dispbuf=digit_tab - '0'];
      dispbuf=digit_tab - '0'];
      dispbuf=symbol_tab; // '-'

      sleep(interval);
    }
}

/**
* Thread of filling the temperature into display buffer
*/
void* temp_to_dispbuf()
{
    char tempbuf;
    int interval=5; // in seconds;
   
    while(1){
      get_temperature(tempbuf, sizeof tempbuf);

      dispbuf=digit_tab-'0'];
      dispbuf=digitdot_tab-'0'];
      dispbuf=digit_tab-'0'];
      
      sleep(interval);
    }
   
}

int main(int argc, char **argv)
{
    pthread_t get_time_thread, get_temp_thread;
    void * thread_ret;

    init_gpio();

    pthread_create( &get_time_thread, NULL, time_to_dispbuf, NULL);
    pthread_create( &get_temp_thread, NULL, temp_to_dispbuf, NULL);

    while (1)
    {

      int i;
      for(i=0;i<DISPBUF_LEN;i++){
            digitalWrite(latchPin, 0);
            shiftOut(dataPin, clockPin, MSBFIRST, 1<<i);
            shiftOut(dataPin, clockPin, MSBFIRST, dispbuf);
            digitalWrite(latchPin, 1);
            usleep(2000);
      }
      
    }

    pthread_join(get_time_thread,&thread_ret);
    pthread_join(get_temp_thread,&thread_ret);
    return 0;
}

ocean 发表于 2014-3-10 08:33:27

这个可以有

4207317 发表于 2014-3-20 12:59:16

能不能直接发一下w1_sun4i.ko这个模块,我的也是3.4.61. 编译不过

soloforce 发表于 2014-3-21 09:25:12

4207317 发表于 2014-3-20 12:59 static/image/common/back.gif
能不能直接发一下w1_sun4i.ko这个模块,我的也是3.4.61. 编译不过

这是我自己编译的内核模块,for CB1.

4207317 发表于 2014-3-22 10:25:31

非常感谢,这个目前我已经搞定了。 是我操作过程中的一个失误。

http://www.fdyu.com/monitor.html

这是我ds18b20的实时温度

Earthman 发表于 2014-3-27 03:22:10

楼主,赞一个

Darwin 发表于 2014-4-1 09:26:11

是一定要让gpio_pin_28对应PB10这个管脚吗?能够随意使用gpio_pin_XX,我一直对这个问题很困扰。

非常感谢

soloforce 发表于 2014-4-1 11:42:41

Darwin 发表于 2014-4-1 09:26 static/image/common/back.gif
是一定要让gpio_pin_28对应PB10这个管脚吗?能够随意使用gpio_pin_XX,我一直对这个问题很困扰。

非常感谢 ...

gpio_pin_xxx 中的xxx 要和你自己定义的gpio_num = yyy 有关系,必须满足xxx<=yyy;

xxx 不一定非得指定PB10,可以自己指定为在gpio_para段中分配的管脚。

Darwin 发表于 2014-4-1 16:09:14

soloforce 发表于 2014-4-1 11:42 static/image/common/back.gif
gpio_pin_xxx 中的xxx 要和你自己定义的gpio_num = yyy 有关系,必须满足xxx

gpio_pin_28 = port:PB10<0><default><default><0>


gpio = 28

另外这要这两个参数保持一致就可以了是吗,如果我把这两个参数的28都换成29,one-wire驱动也应该能够识别吧?

非常感谢...

soloforce 发表于 2014-4-1 21:04:45

应该是的。
页: [1] 2
查看完整版本: Cubieboard1显示DS18B20温度信息到LED