Roots4thought
Posts: 12
Joined: Wed Dec 30, 2015 9:08 pm

Ds18b20/w1-therm

Thu Dec 31, 2015 3:23 pm

I'm having an issue getting my pi2 b to recognize my ds18b20 sensors. So far this is what Ive tried.

1.) download and install fresh images of raspbian. I have tried all three major options between noobs, wheezy and Jessie. I have an 8gb and a 16gb micro ad card that I have tried. I use sd formater and sudo dd bs=1m if=(name of my file) of=/dev/diskn. Raspbian seems to load and work as normal in all installs on either card. Have tried sudo apt-get update, sudo apt-get upgrade and sudo rpi-update. Sudo rpi-update seems to break the Jessie install.

2.) hook up one of my 6 different sensors to the pi. I have 5 waterproof vktec sensors (ds18b20) and one "brick" (ds18b20 on a board with a pull-up resistor already on the board) from dfrobot. I wire 3.3v (pin 1) to red or 5v (pin 2), ground/black to ground (pin 6) and data (yellow on vktec and green on dfrobot brick) to pin 7 (gpio 4) with a 4.7k pull-up resistor between power and data on the vktec ones. When I put a multi meter on pin 1 (red/positive) and pin 6 (black/ground) I get 3.3 volts

3.) I add dtoverlay=w1-gpio to /boot/config.txt and reboot. This is where the issue starts. When I use lsmod to see what modules have loaded, I see that wire has loaded as well as w1-gpio but w1-therm does not load. I have tried all sorts of combinations of sudo modprobe w1-therm or w1-therm in /etc/modules and can get the module to load that way (not sure if this is "normal" behavior or not) according to lsmod. This is the same no matter if I use noobs, wheezy or Jessie. I have also tried to add device_tree= Into my /boot/config.txt and just load wire,w1-gpio and w1-therm at startup in /etc/modules. Have also tried different versions of dtoverlay=w1-gpio,gpiopin=gpio4 with or without the /etc/modules file loading modules at startup or just commented out.

4.) I change the directory to cd /sys/bus/w1/devices and list the contents of the folder. I only get the w1_master_bus. Sometimes I also get obscure 00-xxxxxx readings once in a while which the xxxxx changes from 0400000000 to 0b00000000 to 0800000 etc,etc. From what Ive read, the 00-xxxxxx is usually related to loose wiring or bad wiring but I do not believe this is the issue since this happens with the "brick" sensor as well as the vktec waterproof versions.


I have searched and searched looking for a solution to my issue and can not seem to find one.
I have posted on another sight and can not seem to get an answer.

My goal is to use this pi as a brewery automation device using strangebrew elsinore by Doug Edey and without temp monitoring I can not make this happen.
Attachments
image.jpeg
Pi gpio pins
image.jpeg (49.43 KiB) Viewed 5698 times
image.jpeg
Breadboard with vktec setup
image.jpeg (45.06 KiB) Viewed 5698 times
Last edited by Roots4thought on Fri Jan 01, 2016 6:04 pm, edited 2 times in total.

User avatar
DougieLawson
Posts: 36576
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website Twitter

Re: Ds18b20/w1-therm

Thu Dec 31, 2015 5:39 pm

Are your ds18b20s using parasitic power?

There's a whole bunch of parms for the 1-wire module and a special one for external pullup.

Code: Select all

Name:   w1-gpio
Info:   Configures the w1-gpio Onewire interface module.
        Use this overlay if you *don't* need a GPIO to drive an external pullup.
Load:   dtoverlay=w1-gpio,<param>=<val>
Params: gpiopin                  GPIO for I/O (default "4")

        pullup                   Non-zero, "on", or "y" to enable the parasitic
                                 power (2-wire, power-on-data) feature


Name:   w1-gpio-pullup
Info:   Configures the w1-gpio Onewire interface module.
        Use this overlay if you *do* need a GPIO to drive an external pullup.
Load:   dtoverlay=w1-gpio-pullup,<param>=<val>
Params: gpiopin                  GPIO for I/O (default "4")

        pullup                   Non-zero, "on", or "y" to enable the parasitic
                                 power (2-wire, power-on-data) feature

        extpullup                GPIO for external pullup (default "5")
Note: Having anything humorous in your signature is completely banned on this forum. Wear a tin-foil hat and you'll get a ban.

Any DMs sent on Twitter will be answered next month.

This is a doctor free zone.

Roots4thought
Posts: 12
Joined: Wed Dec 30, 2015 9:08 pm

Re: Ds18b20/w1-therm

Thu Dec 31, 2015 6:04 pm

No sir, not using parasite power. Thanks for the reply!

User avatar
joan
Posts: 14473
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Ds18b20/w1-therm

Thu Dec 31, 2015 6:44 pm

I just did a quick experiment. I have no modules blacklisted and /etc/modules has the single entry i2c-dev.

With dtoverlay=w1-gpio commented out and reboot.
  • No /sys/bus/w1
  • lsmod has no w1 entries.
With dtoverlay=w1-gpio in and reboot, but no devices connected
  • /sys/bus/w1 is present
  • lsmod has the following w1 entries: w1_gpio, wire, cn
Upon connecting a w1 device (live)
  • /sys/bus/w1 is present with devices
  • lsmod has the following w1 entries: w1_gpio, wire, cn, w1-therm

danjperron
Posts: 3421
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: Ds18b20/w1-therm

Thu Dec 31, 2015 6:54 pm

Your protoboard picture is not very good. But I notice that the resistor doesn't look to be connected to the data pin of the sensor. It is between the ground and the sensor data pin (left open).

The resistor needs to be connected to 3.3V and to the sensors data pin.

Roots4thought
Posts: 12
Joined: Wed Dec 30, 2015 9:08 pm

Re: Ds18b20/w1-therm

Thu Dec 31, 2015 7:33 pm

@danjperron, thanks for the reply... The picture is just fuzzy, the resistor is between 3.3v and data, just bent a little funny so it looks like it's ground.

On the other sight, Joan was so kind to point me in your direction. She told me that you have that bitbanging application for the ds18b20. I'm a new to Linux user and can't figure out what I'm supposed to do with the code as it is. Maybe you have already done a write up on how to install and use your code and you could point me to that? All that I have read around the internet points twords you being "the man" who knows all about the ds18b20... Does the schmoozing assist in recruiting your expertise? Hope so.

@joan, thanks so much for your help so far. I'll get this one way or another!

User avatar
RogerW
Posts: 286
Joined: Sat Dec 20, 2014 12:15 pm
Location: London UK

Re: Ds18b20/w1-therm

Fri Jan 01, 2016 9:29 am

I cannot help with your currrent problem but I expect joan is on the right track (she usually is). When you get the connection sorted this code might help. I used Raspbian Jessie so you might need to add a sudo if you are using wheezy. The first file contains a class object (DS18B20). If you do not use it as is you might find the comments useful.

Code: Select all

# ds18b20.py
# written by Roger Woollett

import os
import glob
import time

class DS18B20:
	# much of this code is lifted from Adafruit web site
	# This class can be used to access one or more DS18B20 temperature sensors
	# It uses OS supplied drivers and one wire support must be enabled
	# To do this add the line
	# dtoverlay=w1-gpio
	# to the end of /boot/config.txt
	#
	# The DS18B20 has three pins, looking at the flat side with the pins pointing
	# down pin 1 is on the left
	# connect pin 1 to GPIO ground
	# connect pin 2 to GPIO 4 *and* GPIO 3.3V via a 4k8 (4800 ohm) pullup resistor
	# connect pin 3 to GPIO 3.3V
	# You can connect more than one sensor to the same set of pins
	# Only one pullup resistor is required
	
	def __init__(self):
		# load required kernel modules
		os.system('modprobe w1-gpio')
		os.system('modprobe w1-therm')
		
		# Find file names for the sensor(s)
		base_dir = '/sys/bus/w1/devices/'
		device_folder = glob.glob(base_dir + '28*')
		self._num_devices = len(device_folder)
		self._device_file = list()
		i = 0
		while i < self._num_devices:
			self._device_file.append(device_folder[i] + '/w1_slave')
			i += 1
		
	def _read_temp(self,index):
		# Issue one read to one sensor
		# you should not call this directly
		f = open(self._device_file[index],'r')
		lines = f.readlines()
		f.close()
		return lines
		
	def tempC(self,index = 0):
		# call this to get the temperature in degrees C
		# detected by a sensor
		lines = self._read_temp(index)
		retries = 5
		while (lines[0].strip()[-3:] != 'YES') and (retries > 0):
			# read failed so try again
			time.sleep(0.1)
			#print('Read Failed', retries)
			lines = self._read_temp(index)
			retries -= 1
			
		if retries == 0:
			return 998
			
		equals_pos = lines[1].find('t=')
		if equals_pos != -1:
			temp = lines[1][equals_pos + 2:]			
			return float(temp)/1000
		else:
			# error
			return 999
			
	def device_count(self):
		# call this to see how many sensors have been detected
		return self._num_devices
The second file contains a simple test program

Code: Select all

# Temp.py

from ds18b20 import DS18B20	
	
# test temperature sensors
x = DS18B20()
count=x.device_count()
i = 0
while i < count:
	print(x.tempC(i))
	i += 1
Put both files in the same directory. It should show the temperature from multiple sensors.

danjperron
Posts: 3421
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: Ds18b20/w1-therm

Fri Jan 01, 2016 1:16 pm

Your picture is one sensor connected only! I hope.

Did you try to swap the yellow and the red. I know that some sensors don't have the correct color code.


This is the link of my user code modified from Albert Einstein , not the real one ;-), for python
viewtopic.php?p=869599&sid=ab3baf34c5b3 ... e7#p869599

This is my c version that I just modified with a better 1usec timer from Albert Einstein set for the Pi2.

Just nano DS18B20Scan.c and paste the code

Code: Select all

// modified version to read DS18B20 in bit banging
//
//1 january 2016
// add  1 microsecond function delay
// from // Gladkikh Artem  (Albert Einstein user raspberrypi.org)





// 26 June 2014
//
// Add fix for no input pull-up or sensor
// Set Start Acquistion waiting delay  using a constant of 750ms
// Add set aquisition resolution into the eerom config (-9bits,-10bits,-11bits,-12bits(default)
// Add parameter to change the Wait time after start of aquisition (check pdf info for correct timing).
// Add possibility to use 64bits sensor ID from a file.

//  25 June 2014
// 
// Updated version
// Search rom  code command added
// More than one sensor  on the same pin
//
// Argument:
//  -s        =>  just scan and display the 64 bits rom code of the probe
//  -gpio n   =>  Specify pin other than GPIO10
//
//  Step process
//  1- Start Conversion using SKIP ROM  (all devices)
//  2- Search for sensor. When one is found, Display the temperature


//  24 May 2014
//  Daniel Perron
//
// Use At your own risk




//
//  How to access GPIO registers from C-code on the Raspberry-Pi
//  Example program
//  15-January-2012
//  Dom and Gert
//  Revised: 15-Feb-2013


// Access from ARM Running Linux

//#define BCM2708_PERI_BASE        0x20000000
#define BCM2708_PERI_BASE        0x3F000000
#define GPIO_BASE                (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */


#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <sched.h>



#define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024)

int  mem_fd;
void *gpio_map;

// I/O access
volatile unsigned *gpio;


// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
#define OUT_GPIO(g) *(gpio+((g)/10)) |=  (1<<(((g)%10)*3))
#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))

#define GPIO_SET *(gpio+7)  // sets   bits which are 1 ignores bits which are 0
#define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0

#define GPIO_READ(g)  (*(gpio + 13) &= (1<<(g)))


#define DS18B20_SKIP_ROM 		0xCC
#define DS18B20_CONVERT_T 		0x44
#define DS18B20_MATCH_ROM               0x55
#define DS18B20_SEARCH_ROM		0XF0
#define DS18B20_READ_SCRATCHPAD         0xBE
#define DS18B20_WRITE_SCRATCHPAD        0x4E
#define DS18B20_COPY_SCRATCHPAD         0x48


unsigned char ScratchPad[9];
double  temperature;
int   resolution;

void setup_io();



unsigned short DS_PIN=10;
unsigned short ArgResolution=0;
unsigned short ArgScan=0;
unsigned short ArgFile=0;
unsigned short ArgWaitTime=750;
char FileName[256];

int  DoReset(void)
{
 int loop;

   INP_GPIO(DS_PIN);


   usleep(10);

   INP_GPIO(DS_PIN);
   OUT_GPIO(DS_PIN);

   // pin low for 480 us
   GPIO_CLR=1<<DS_PIN;
   usleep(480);
   INP_GPIO(DS_PIN);
   usleep(60);
   if(GPIO_READ(DS_PIN)==0)
   {
     usleep(420);
     return 1;
   }
  return 0;
}

#define DELAY1US  DelayMicrosecondsNoSleep(1);


void  smalldelay(void)
{
  int loop2;
   for(loop2=0;loop2<50;loop2++);
}




void DelayMicrosecondsNoSleep (int delay_us)
{
   long int start_time;
   long int time_difference;
   struct timespec gettime_now;

   clock_gettime(CLOCK_REALTIME, &gettime_now);
   start_time = gettime_now.tv_nsec;      //Get nS value
   while (1)
   {
      clock_gettime(CLOCK_REALTIME, &gettime_now);
      time_difference = gettime_now.tv_nsec - start_time;
      if (time_difference < 0)
         time_difference += 1000000000;            //(Rolls over every 1 second)
      if (time_difference > (delay_us * 1000))      //Delay for # nS
         break;
   }
}







void WriteByte(unsigned char value)
{
  unsigned char Mask=1;
  int loop;

   for(loop=0;loop<8;loop++)
     {
       INP_GPIO(DS_PIN);
       OUT_GPIO(DS_PIN);
       GPIO_CLR= 1 <<DS_PIN;

       if((value & Mask)!=0)
        {
           DELAY1US
            INP_GPIO(DS_PIN);
           usleep(60);

        }
        else
        {
           usleep(60);
           INP_GPIO(DS_PIN);
           usleep(1);
        }
      Mask*=2;
      usleep(60);
    }


   usleep(100);
}

void WriteBit(unsigned char value)
{
   INP_GPIO(DS_PIN);
   OUT_GPIO(DS_PIN);
   GPIO_CLR=1 <<DS_PIN;
   if(value)
    {
      DELAY1US
      INP_GPIO(DS_PIN);
      usleep(60);
    }
   else
    {
      usleep(60);
      INP_GPIO(DS_PIN);
      usleep(1);
     }
   usleep(60);
}
 




unsigned char ReadBit(void)
{
   unsigned char rvalue=0;
   INP_GPIO(DS_PIN);
   OUT_GPIO(DS_PIN);
   // PIN LOW
   GPIO_CLR= 1 << DS_PIN;
   DELAY1US
   // set INPUT
   INP_GPIO(DS_PIN);
   DELAY1US
   DELAY1US
   DELAY1US
   if(GPIO_READ(DS_PIN)!=0)
    rvalue=1;
   usleep(60);
   return rvalue;
}

unsigned char ReadByte(void)
{

   unsigned char Mask=1;
   int loop;
   unsigned  char data=0;

  int loop2;


   for(loop=0;loop<8;loop++)
     {
       //  set output
       INP_GPIO(DS_PIN);
       OUT_GPIO(DS_PIN);
       //  PIN LOW
       GPIO_CLR= 1<<DS_PIN;
       DELAY1US
       //  set input
       INP_GPIO(DS_PIN);
       // Wait  2 us
       DELAY1US
       DELAY1US
       DELAY1US
       if(GPIO_READ(DS_PIN)!=0)
       data |= Mask;
       Mask*=2;
       usleep(60);
      }

    return data;
}



int ReadScratchPad(void)
{
   int loop;

       WriteByte(DS18B20_READ_SCRATCHPAD);
       for(loop=0;loop<9;loop++)
         {
          ScratchPad[loop]=ReadByte();
        }
}

unsigned char  CalcCRC(unsigned char * data, unsigned char  byteSize)
{
   unsigned char  shift_register = 0;
   unsigned char  loop,loop2;
   char  DataByte;
 
   for(loop = 0; loop < byteSize; loop++)
   {
      DataByte = *(data + loop);
      for(loop2 = 0; loop2 < 8; loop2++)
      {
         if((shift_register ^ DataByte)& 1)
         {
            shift_register = shift_register >> 1;
            shift_register ^=  0x8C;
         }
         else
            shift_register = shift_register >> 1;
         DataByte = DataByte >> 1;
      }
   }
   return shift_register;
}

char  IDGetBit(unsigned long long *llvalue, char bit)
{
  unsigned long long Mask = 1ULL << bit;

  return ((*llvalue & Mask) ? 1 : 0);
}


unsigned long long   IDSetBit(unsigned long long *llvalue, char bit, unsigned char newValue)
{
  unsigned long long Mask = 1ULL << bit;

  if((bit >= 0) && (bit < 64))
  {
  if(newValue==0)
   *llvalue &= ~Mask;
  else
   *llvalue |= Mask;
   }
  return *llvalue;
}


void SelectSensor(unsigned  long long ID)
{
int BitIndex;
char Bit;


WriteByte(DS18B20_MATCH_ROM);

for(BitIndex=0;BitIndex<64;BitIndex++)
   WriteBit(IDGetBit(&ID,BitIndex));

}

int  SearchSensor(unsigned long long * ID, int * LastBitChange)
{
 int BitIndex;
  char Bit , NoBit;


if(*LastBitChange <0) return 0;

// Set bit at LastBitChange Position to 1
// Every bit after LastbitChange will be 0

if(*LastBitChange <64)
{

   IDSetBit(ID,*LastBitChange,1);
   for(BitIndex=*LastBitChange+1;BitIndex<64;BitIndex++)
    IDSetBit(ID,BitIndex,0);
}

*LastBitChange=-1;

if(!DoReset()) return -1;


WriteByte(DS18B20_SEARCH_ROM);

  for(BitIndex=0;BitIndex<64;BitIndex++)
    {

      NoBit = ReadBit();
      Bit = ReadBit();

     if(Bit && NoBit)
        return -2;

     if(!Bit && !NoBit)
        {
          // ok 2 possibilities
//          printf("B");
          if(IDGetBit(ID,BitIndex))
            {
               // Bit High already set 
                WriteBit(1);
             }
          else
             {
               // ok let's try LOW value first
               *LastBitChange=BitIndex;
                WriteBit(0);
             }
         }
      else if(!Bit)
        { 
//	printf("1");
         WriteBit(1);
         IDSetBit(ID,BitIndex,1);
        }
      else
        {
        //printf("0");
        WriteBit(0);
        IDSetBit(ID,BitIndex,0);
        }
//   if((BitIndex % 4)==3)printf(" ");
    }
//
// printf("\n");
  return 1;



}







int ReadSensor(unsigned long long ID)
{
  int RetryCount;
  int loop;
  unsigned char  CRCByte;
  union {
   short SHORT;
   unsigned char CHAR[2];
  }IntTemp;


  time_t t = time(NULL);
  struct tm tm = *localtime(&t);

  temperature=-9999.9;

  for(RetryCount=0;RetryCount<10;RetryCount++)
  {

   if(!DoReset()) continue;

   // start a conversion
   SelectSensor(ID);

  if(!ReadScratchPad()) continue;

//     for(loop=0;loop<9;loop++)
//       printf("%02X ",ScratchPad[loop]);
//     printf("\n");fflush(stdout);

  // OK Check sum Check;
  CRCByte= CalcCRC(ScratchPad,8);

  if(CRCByte!=ScratchPad[8]) continue;;

  //Check Resolution
   resolution=0;
   switch(ScratchPad[4])
   {

     case  0x1f: resolution=9;break;
     case  0x3f: resolution=10;break;
     case  0x5f: resolution=11;break;
     case  0x7f: resolution=12;break;
   }

   if(resolution==0) continue;
    // Read Temperature

    IntTemp.CHAR[0]=ScratchPad[0];
    IntTemp.CHAR[1]=ScratchPad[1];


    temperature =  0.0625 * (double) IntTemp.SHORT;

    ID &= 0x00FFFFFFFFFFFFFFULL;
    printf("%02llX-%012llX : ",ID & 0xFFULL, ID >>8);

    printf("%02d bits  Temperature: %6.2f +/- %4.2f Celsius\n", resolution ,temperature, 0.0625 * (double)  (1<<(12 - resolution)));

    return 1;
    }

  return 0;

}



int GlobalStartConversion(void)
{
   int retry=0;
   int maxloop;

   while(retry<10)
   {
     if(!DoReset())
      usleep(10000);
     else
      {
       WriteByte(DS18B20_SKIP_ROM);
       WriteByte(DS18B20_CONVERT_T);
       maxloop=0;

#define USE_CONSTANT_DELAY
#ifdef USE_CONSTANT_DELAY
       usleep(ArgWaitTime * 1000);
       return 1;
#else
      // wait until ready
      while(!ReadBit())
      {
       maxloop++;
       if(maxloop>100000) break;
      }

      if(maxloop<=100000)  return 1;
#endif
     }
    retry++;
   }
   return 0;


}


void WriteScratchPad(unsigned char TH, unsigned char TL, unsigned char config)
{

    // First reset device

    DoReset();

    usleep(10);
    // Skip ROM command
     WriteByte(DS18B20_SKIP_ROM);


     // Write Scratch pad

    WriteByte(DS18B20_WRITE_SCRATCHPAD);

    // Write TH

    WriteByte(TH);

    // Write TL

    WriteByte(TL);

    // Write config

    WriteByte(config);
}


void  CopyScratchPad(void)
{

   // Reset device
    DoReset();
    usleep(1000);

   // Skip ROM Command

    WriteByte(DS18B20_SKIP_ROM);

   //  copy scratch pad

    WriteByte(DS18B20_COPY_SCRATCHPAD);
    usleep(100000);
}

void ChangeSensorsResolution(int resolution)
{
   int config=0;

        switch(resolution)
         {
           case 9:  config=0x1f;break;
           case 10: config=0x3f;break;
           case 11: config=0x5f;break;
           default: config=0x7f;break;
         }
      WriteScratchPad(0xff,0xff,config);
      usleep(1000);
      CopyScratchPad();
}



void ScanForSensor(void)
{
  unsigned long long  ID=0ULL;
  int  NextBit=64;
  int  _NextBit;
  int  rcode;
  int retry=0;
  unsigned long long  _ID;
  unsigned char  _ID_CRC;
  unsigned char _ID_Calc_CRC;
  unsigned char  _ID_Family;

  while(retry<10){
   _ID=ID;
   _NextBit=NextBit;
   rcode=SearchSensor(&_ID,&_NextBit);
    if(rcode==1)
     {
        _ID_CRC =  (unsigned char)  (_ID>>56);
        _ID_Calc_CRC =  CalcCRC((unsigned char *) &_ID,7);
        if(_ID_CRC == _ID_Calc_CRC)
        {
         if(ArgScan==0)
          {
           if(ReadSensor(_ID))
            {
              ID=_ID;
              NextBit=_NextBit;
              retry=0;
            }
           else
             retry=0;
          }
          else
           {
            ID=_ID;
            NextBit=_NextBit;
            printf("%016llX\n",ID);
           }
        }
        else retry++;
     }
    else if(rcode==0 )
     break;
    else
     retry++;
}
}



void DecodeArg(int argc, char ** argv)
{

   int idx=1;

   while(idx<argc)
    {
       if(strcmp(argv[idx],"-gpio")==0)
            DS_PIN = atoi(argv[++idx]);
       else if(strcmp(argv[idx],"-9bits")==0)
            ArgResolution=9;
       else if(strcmp(argv[idx],"-10bits")==0)
            ArgResolution=10;
       else if(strcmp(argv[idx],"-11bits")==0)
            ArgResolution=11;
       else if(strcmp(argv[idx],"-12bits")==0)
            ArgResolution=12;
       else if(strcmp(argv[idx],"-s")==0)
         ArgScan=1;
       else if(strcmp(argv[idx],"-t")==0)
           ArgWaitTime = atoi(argv[++idx]);
       else if(strcmp(argv[idx],"-f")==0)
        {
          ArgFile=1;
          strcpy(FileName,argv[++idx]);
        }
       else
        {
         printf("Unknown argument %s! ",argv[idx]);
         exit(0);
        }
       idx++;
     }
}


void ReadSensorsFromFile(char * Filename)
{
   FILE * src;
   char LineBuffer[256];
   unsigned long long SensorID;

   src = fopen(Filename,"rt");
   if(src==NULL) return;
   while(1)
   {
    if(fgets(LineBuffer,256,src)==NULL) break;
    if(sscanf(LineBuffer,"%llx",&SensorID)==1)
        ReadSensor(SensorID);
   }
  fclose(src);
}


// Adafruit   set_max_priority and set_default priority add-on

void set_max_priority(void) {
  struct sched_param sched;
  memset(&sched, 0, sizeof(sched));
  // Use FIFO scheduler with highest priority for the lowest chance of the kernel context switching.
  sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
  sched_setscheduler(0, SCHED_FIFO, &sched);
}

void set_default_priority(void) {
  struct sched_param sched;
  memset(&sched, 0, sizeof(sched));
  // Go back to default scheduler with default 0 priority.
  sched.sched_priority = 0;
  sched_setscheduler(0, SCHED_OTHER, &sched);
}


int main(int argc, char **argv)
{
  int loop;
  int Flag=0;
  // Set up gpi pointer for direct register access

  DecodeArg(argc,argv);

  setup_io();

  // Check for pull up resistor
  // Signal  input should be high

  // Set PIN to INPUT MODe
  INP_GPIO(DS_PIN);

  Flag=0;
  for(loop=0;loop<100;loop++)
   {
     usleep(1000);
     if(GPIO_READ(DS_PIN)!=0)
        {
          Flag=1;
          break;
        }
   }

   if(Flag==0)
    {
      printf("*** Error Unable to detect Logic level 1. No pull-up ?\n");
      exit(-1);
    }

    if(ArgResolution>0)
      {
        // need to change resolution
        ChangeSensorsResolution(ArgResolution);
        // do it twice just in case
        ChangeSensorsResolution(ArgResolution);
     }


    if(GlobalStartConversion()==0)
    {
      printf("*** Error Unable to detect any DS18B20 sensor\n");
      exit(-2);
    }

  set_max_priority();


   if(ArgFile)
   {
     ReadSensorsFromFile(FileName);
   }
   else
     ScanForSensor();

  set_default_priority(); 

  return 0;

} // main


//
// Set up a memory regions to access GPIO
//
void setup_io()
{
   /* open /dev/mem */
   if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
      printf("can't open /dev/mem \n");
      exit(-1);
   }

   /* mmap GPIO */
   gpio_map = mmap(
      NULL,             //Any adddress in our space will do
      BLOCK_SIZE,       //Map length
      PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory
      MAP_SHARED,       //Shared with other processes
      mem_fd,           //File to map
      GPIO_BASE         //Offset to GPIO peripheral
   );

   close(mem_fd); //No need to keep mem_fd open after mmap

   if (gpio_map == MAP_FAILED) {
      printf("mmap error %d\n", (int)gpio_map);//errno also set!
      exit(-1);
   }

   // Always use volatile pointer!
   gpio = (volatile unsigned *)gpio_map;


} // setup_io
just compile with

Code: Select all

gcc -o DS18B20Scan -lrt DS18B20Scan.c
Once compiled , move your data pin to an unused GPIO pin. Be sure that GPIO doesn't have any alternate function.
You can't use the 1W pin.

and type

Code: Select all

sudo ./DS18B20Scan -gpio  X 
Where X is the GPIO pin (BCM mode) like "-gpio 21" ( GPIO21 pin 40)

Roots4thought
Posts: 12
Joined: Wed Dec 30, 2015 9:08 pm

Re: Ds18b20/w1-therm

Sun Jan 03, 2016 5:59 pm

Well, I didn't think of it earlier but, I changed my overlay to say dtoverlay=w1-gpio,gpiopin=21 and moved my data wire to gpio 21 (pin 40). Tada!!! Working temp sensor.

With this being said, I tried gpiopin=4 and still have no devices listed.

Does this mean my gpio4 is shot?
How can I test this?

magitech
Posts: 1
Joined: Thu Aug 25, 2016 9:18 am

Re: Ds18b20/w1-therm

Thu Aug 25, 2016 10:28 am

Hi,
i have the same problem that you have reported and I have used your solution.
First of all thanks for sharing it. Second, have you understood what was wrong with the default configuration?

Thanks,
Fabio

Roots4thought
Posts: 12
Joined: Wed Dec 30, 2015 9:08 pm

Re: Ds18b20/w1-therm

Fri Dec 30, 2016 1:05 am

You're welcome. No, I never figured out what the issue was. Gpio 4 is no good for my use.

mrh53
Posts: 5
Joined: Tue Jan 03, 2017 3:23 pm

Re: Ds18b20/w1-therm

Tue Jan 03, 2017 5:59 pm

DougieLawson wrote:Are your ds18b20s using parasitic power?

There's a whole bunch of parms for the 1-wire module and a special one for external pullup.

Code: Select all

Name:   w1-gpio
Info:   Configures the w1-gpio Onewire interface module.
        Use this overlay if you *don't* need a GPIO to drive an external pullup.
Load:   dtoverlay=w1-gpio,<param>=<val>
Params: gpiopin                  GPIO for I/O (default "4")

        pullup                   Non-zero, "on", or "y" to enable the parasitic
                                 power (2-wire, power-on-data) feature


Name:   w1-gpio-pullup
Info:   Configures the w1-gpio Onewire interface module.
        Use this overlay if you *do* need a GPIO to drive an external pullup.
Load:   dtoverlay=w1-gpio-pullup,<param>=<val>
Params: gpiopin                  GPIO for I/O (default "4")

        pullup                   Non-zero, "on", or "y" to enable the parasitic
                                 power (2-wire, power-on-data) feature

        extpullup                GPIO for external pullup (default "5")
I have been looking all over trying to find this type of information. Where is this info located?

Thanks.

User avatar
rpdom
Posts: 15592
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: Ds18b20/w1-therm

Tue Jan 03, 2017 7:05 pm

mrh53 wrote:I have been looking all over trying to find this type of information. Where is this info located?
In /boot/overlays/README

mrh53
Posts: 5
Joined: Tue Jan 03, 2017 3:23 pm

Re: Ds18b20/w1-therm

Tue Jan 03, 2017 8:55 pm

Thanks. I had not found that file, though I think some of the information is now outdated. I had added to my earlier reply that `modinfo w1-gpio` expect an int. anytime I have tried to set pullup=on or pullup="on" modprobe complains of an invalid argument. Possibly I don't know how to properly quote on so that is is a boolean.

from git for w1-gpio.c:

static int w1_gpio_pullup = 0;
static int w1_gpio_pullup_orig = 0;
module_param_named(pullup, w1_gpio_pullup, int, 0);

I get the feeling the sysfs permissions of 0 in module_param_named(....,0); prevents the /sys/module/w1-gpio/parameters/pullup file from being generated, or at least visible. Is this true?

I cannot find any parameters directories in /sys/module/*/parameters so I cannot check other definitions for comparison.

mrh53
Posts: 5
Joined: Tue Jan 03, 2017 3:23 pm

Re: Ds18b20/w1-therm

Tue Jan 03, 2017 9:06 pm

I have since grep'd all log files in /var/log (excluding subdirectories) and found no instances of "pullup" other than when I had poorly formed the assignment. How does one determine that the module is loaded as intended if the parameters/pullup file is not written and no postings are made to log files? Is it possible there is a log file located elsewhere from /var/log?

mrh53
Posts: 5
Joined: Tue Jan 03, 2017 3:23 pm

Re: Ds18b20/w1-therm

Tue Jan 03, 2017 10:00 pm

I have reviewed the code for one of the modules on my ubuntu system that has a parameters directory. The sysfs flags for all the parameters defined in the code are 644 and all parameters are present in the parameters directory. Apparently the sysfs flag value in the module_param_named(name, name, type, sysfsflags) function does prevent the parameters from being published to the parameters directory. I may try my hand at compiling my own version of w1-gpio setting the sysflags value to 644. I would sure like to know that the module is loaded as intended.

I imagine sysflags=0 as a default on the module parameters is a nod toward minimising ram resources used for info few care about. Changing to 644 while developing or becoming familiar with a new module may be useful.

User avatar
rpdom
Posts: 15592
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: Ds18b20/w1-therm

Tue Jan 03, 2017 10:27 pm

mrh53 wrote:Thanks. I had not found that file, though I think some of the information is now outdated. I had added to my earlier reply that `modinfo w1-gpio` expect an int. anytime I have tried to set pullup=on or pullup="on" modprobe complains of an invalid argument. Possibly I don't know how to properly quote on so that is is a boolean.
Why are you using modprobe?

All you need to do for the DS18B20 is have the correct dtoverlay line in /boot/config.txt. You don't need any modprobes.

mrh53
Posts: 5
Joined: Tue Jan 03, 2017 3:23 pm

Re: Ds18b20/w1-therm

Tue Jan 03, 2017 11:25 pm

I agree that modprobe is not required for a properly configured system. However, I have a strong interest in knowing how to explore what's happening when I do not get the results I anticipate. Modprobe is one of those tools as is modinfo, lsmod and the log files. My whole discussion resulted from trying to obtain results that others claimed using versions of kernel unknown to me. As I tried to unravel this the general assistance offered by others regarding monitoring the parameter values used by installed modules failed because of no entries being made to log files or stored under /sys/module/*/parameters.

Couple all this to the fact that the first generic linux source code I found does not use pullup, but rather enable-pullup and as part of w1, or w1-int (I can't recall) and not w1-gpio, I felt compelled to enhance my very limited understanding of how modules are loaded and unloaded. I have chosen to log my findings in the case that others with a similar limitation of knowledge as I have can be saved from some of the explorations I have made.

As so far as the dt system, that is still a mystery to me and I do not know how it interacts with insmod to make sure the modules are properly configured at loading. Having it "just work" is fine till it doesn't, so I am now trying to learn more about that. At the end I expect to have a complete understanding how all parameters used by w1-gpio are initialized the device trees or through other configuration files.

Besides, I'm failing at understanding how to start graphical systemd user services prior to login so this gives me a break.

If logging my progress here is not appropriate I will continue in private. I am hoping to save others at my level of familiarity with linux and the raspian distribution some time as they encounter the same questions as I have.

(Yes, I have been accused of being somewhat bull-headed about trying to understand things. ;)

Return to “Automation, sensing and robotics”