OneWire bus master implementation

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

OneWire bus master implementation

2,807 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jharwood on Wed Jan 19 19:30:53 MST 2011
An application that I have in mind for the LPC1343 involves a few DS18S20 temperature sensors. A quick search for a OneWire bus master solution on LPC didn't return anything much, so I set about making one.

If anyone is interested, the attached zip file contains a couple of source files that can be added to a project that needs OneWire bus master functionality. Feedback of any kind would be most welcome.

Edit: A new improved version is now attached to post # 7 below.
0 Kudos
37 Replies

1,464 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Nicogp on Wed Feb 17 07:46:07 MST 2016
Hello Pinchi, I'm trying your code and can not get temperature sensing

"LPC1769_DS18S20 Init...Feb 17 2016 10:04:20
found: 0xd70000053c6e3b28 "

and no more :(

can you helpme??
I'm using a single sensor
0 Kudos

1,464 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Pinchi on Thu Apr 25 10:14:54 MST 2013
Hey Guys,

I have the working code for the multiple DS18S20 temperature sensors for LPC1769. Included is the main function too. :)

I am facing a problem now. I have the sensors arranged in a series. I use about 36 sensors and use them on one or maximum two pins.

1) Will I have electrical limitations for the number of sensor in one line?
2) How can I read the sensors in the order of their arrangement?
3) How will I know which sensor has what address?

Thanks for you help.
0 Kudos

1,464 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by hens on Wed Mar 06 17:15:05 MST 2013
I downloaded the original zipfile and began modifying to work with DS28EC20 (20Kb EEPROM) on a LPC11U14 (CortexM0 with USB).  First of all, this is a really nicely-written piece of code!!  Thank you for sharing!

At least for my target,
#define PRESCALE ((SystemCoreClock/LPC_SYSCON->SYSAHBCLKDIV)/(1000000ul *2))
results in about 1/2 the expected pulse widths.

It should be-
#define PRESCALE ((SystemCoreClock/LPC_SYSCON->SYSAHBCLKDIV)/1000000ul - 1)

Maybe this explains some of the unexpected bandwidth limitations you were seeing?
0 Kudos

1,464 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Pinchi on Tue Feb 19 04:51:26 MST 2013
Sorry for my miscommunication. I did see the code in #20 and I will try to modify it. I am using the code that I have attached earlier. Thanks a lot anyway!
0 Kudos

1,464 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ex-kayoda on Mon Feb 18 14:37:37 MST 2013

Quote: Pinchi
I do not know which function you are referring too.



Sample code function of[COLOR=Red] #20 in this thread[/COLOR] :eek:
0 Kudos

1,464 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Pinchi on Mon Feb 18 13:56:25 MST 2013
Hey Kayoda

I do not know which function you are referring to. I have an altogether different code and it works like a magic with one sensor on the bus.

find it in the attachment. I have to modify this code. Anyway, I have some way from your idea now thanks.
0 Kudos

1,464 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ex-kayoda on Thu Feb 14 12:06:41 MST 2013

Quote: Pinchi

  I am not sure how to manipulate the code yet to suit my needs.



:confused:

What's wrong with [COLOR=Red]ow_find_devices()[/COLOR] :confused:
0 Kudos

1,464 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Pinchi on Thu Feb 14 11:44:32 MST 2013
void StartReadRom() {
    owbuf[0] = CMD_ROM;
    nwrite = 1;
    nread = 8;
    ow_start();
}


Hey Zero, Thanks for the timely response.

I did have a thought in the same lines as you mentioned.

I have the ReadRom[0x33] to read from one sensor on bus. but I have to use SearchRom[0xF0]. And I am powering it externally. I do not have a clear idea yet. I am not sure how to manipulate the code yet to suit my needs. :confused::confused::confused:
0 Kudos

1,464 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Wed Feb 13 04:42:36 MST 2013
AFAIR each DS1820 has it's own unique serial number ;) and your Master can send this 'ROM code' to start a temperature conversion of this specific DS1820 :)

See DS18S20 Datasheet:

Quote:

[B]DS18S20 OPERATION EXAMPLE 1[/B]
In this example there are multiple DS18S20s on the bus and they are using parasite power. The bus master initiates a temperature conversion in a specific DS18S20 and then reads its scratchpad and recalculates the CRC to verify the data.

0 Kudos

1,464 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Pinchi on Wed Feb 13 04:12:25 MST 2013
Hey Guys,

I found the solution for LPC1769 Temperature sensor finally, with lot of help from others and other sources too ;). But I still do have query. How can the board sense more than one sensor on the same bus/GPIO.:confused:?  Any idea?
0 Kudos

1,464 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Pinchi on Mon Jan 28 08:10:34 MST 2013
Hi bgm , Thanks a lot. I am completely new to MC programming and I was trying to figure out. I could not. I did see the manual and I altered to code to set and clear. I am missing something somewhere. I have been on it for 3 days now, maybe wrong methods/idea. I am still unclear.????? :(
0 Kudos

1,464 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by gbm on Fri Jan 25 00:25:29 MST 2013
Read The Fine Manual and look at the description of GPIO. There is no masked access, but there is bit set/clear capability. Use your head and hands and modify the code. I did that some time ago.
0 Kudos

1,464 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Pinchi on Thu Jan 24 12:24:04 MST 2013
Hey,

I am working with LPC1769. I am unable to find the masked access and the pulse timings for the one-wire from post #1. I am unable to find the difference. I am unable to even sense the DS18S20. Any help is appreciated. Thanks.
0 Kudos

1,464 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by mclane on Sun Oct 14 03:49:11 MST 2012
Hi all,

thanks for the work.
I tried to port the solution to the LPC1227, but could not get it working. Here are my findings:

1. The GPIO Helper macros (line 65 ff) do not work.
2. There is no "masked_access" structure in the LPC122x.h. The "mask" does not seem to be equivalent.

So I replaced the helper macros by

#define OW_OUTPUT (LPC_GPIO0->DIR |= (1 << OW_PIN))
#define OW_INPUT (LPC_GPIO0->DIR &= ~(1 << OW_PIN))
#define OW_LOW    (LPC_GPIO0->CLR = 1 << OW_PIN) 
#define OW_HIGH (LPC_GPIO0->SET = (1 << OW_PIN))
#define OW_SENSE (LPC_GPIO0->PIN & (1 << OW_PIN))
and replaced all references to LPC_TMR by LPC_16B0.

ow_init and ow_reset seem to work (I can get ow_reset = 0 / 1 weather or not I have sensors on the bus); however I do not succeed to read temperature values from my 16B20 sensors.  I have used the onewire library from post #20.

Any hint from the community?
0 Kudos

1,464 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by yanvasilij on Wed Sep 19 05:12:48 MST 2012
Thank you for your work!

Can you help me a little with this (LPC11C24):
__task void pdoTask (void)  // on of the RTOS tasks
{
...
     for(;;)
     {
              os_dly_wait (delay);
              ow_read_temp(&temperature, NULL);
         ...
     }
...
}
...
int main (void)
{
...
    LPC_IOCON->R_PIO0_11 = (1<<0);
    ow_init();
    ow_find_devices();
...
os_sys_init(init); // RTOS call
}
Program loops forever on while (ow_state != CONV_COMPLETE) when  ow_read_temp(&temperature, NULL) called on second time. What can be wrong?

Regards, Vasilij.
0 Kudos

1,464 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jharwood on Thu Feb 10 11:19:06 MST 2011
Oops :o  Yes, that return value should be int16_t. Thanks for pointing it out Zero.

Wow! almost -20, that's pretty darned cold!  At least the electrons are traveling a little bit faster along the wire :D
0 Kudos

1,464 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Wed Feb 09 19:46:27 MST 2011
NOTE #1: It's working with LPC11C14 in parasitic mode with 50m cable and 3x DS18S20. Unfortunately it's cold :mad: today so i have to handle negative temperatures and convert unsigned int to int. Perhaps you want to change ow_read_temp(uint16_t ...) to ow_read_temp(int16_t ...).

NOTE #2: To avoid printing floats I'm using (t_val *5) which shows 105 instead of 10.5.

#define SENSORS 3
 
RomType t_sensor[SENSORS];
unsigned short t_val;     //temperature value
short temperature[SENSORS];    //temperature *10 (to avoid float)
unsigned char result=0;     //result
volatile unsigned int msTicks;   //ms counter
unsigned char sensor_counter;   //counter for sensor loop
 
void SysTick_Handler(void)     //Interrupt handler
{
 msTicks++;
}
 
int main(void)
{
...
 SysTick_Config(SystemCoreClock / 1000);//SysTick Timer 1 msec interrupts
 UARTInit(115200);      //uart init 115k
 printf("LPC11_DS18S20 Init..."__DATE__" "__TIME__"\n");
 ow_init();        //init ow
 ow_find_devices();      //find devices and show 64-Bit Serial Code 
 printf("...done\n");
 t_sensor[0].l = 0xe900080225bd2a10ull; //64-Bit Serial Code sensor #1
 t_sensor[1].l = 0x8c00080225dbb910ull; //64-Bit Serial Code sensor #2
 t_sensor[2].l = 0x9200080225f7ff10ull; //64-Bit Serial Code sensor #3
 ...
 while(1)
 {          //loop
...
//read sensors
  for(sensor_counter=0;sensor_counter<SENSORS;sensor_counter++)
  {
   if(ow_read_temp(&t_val,&t_sensor[sensor_counter]))
   {
    printf("Error Sensor %d\n",(sensor_counter+1));
   }
   else
   {
    temperature[sensor_counter] = (t_val *5);  //read uint to int
    printf("Temperature #%d: %d\n",sensor_counter+1,temperature[sensor_counter]);
   }
  }          //end sensor loop
 ... 
 }          //end loop
 return 0 ;
}


Output:
LPC11_DS18S20 Init... Feb 10 2011 02:54:22
found: 0xe900080225bd2a10
found: 0x8c00080225dbb910
found: 0x9200080225f7ff10
...done
Temperature #1: 195
Temperature #2: -125
Temperature #3: -105
Temperature #1: 195
Temperature #2: -125
Temperature #3: -110
Temperature #1: 195
Temperature #2: -125
Temperature #3: -110
0 Kudos

1,464 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jharwood on Wed Feb 09 13:33:33 MST 2011
Mat,

Thanks very much for sharing your findings :)
0 Kudos

1,469 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by mattes on Tue Feb 08 22:13:12 MST 2011
James,

I made a couple of changes to address the issues I was having with the LPC1114:
  - extended all LPC_TMP->MR2 timing  to avoid hang in Timer_IRQHandler()
  - changed timing for ow_reset() to 550 ms. once in a while ow_reset() did not find the sensor signal. The previous timing was too short (too close to the spec'ed minimum in the data sheet 480ms)
  - the improved timing seems to be more robust. Now the code runs even in debug mode with semi hosting enabled.

Attached 'onewire.c' is modded by me (based on your first version)
0 Kudos

1,469 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by mattes on Sat Feb 05 22:44:30 MST 2011
For test I reduced the amount of code in the IRQ func. But it did not make any difference in the behaviour. No matter how little code it was. It is not much going to begin with
except maybe case 0x04.

Changing the timing difference of between MR1 and MR2 finally made a difference.

Interestingly case 0x01 allways occurs on the first interrupt from ow_write(). And than something breaks.

According to the data sheet of the DS18x20, Treq  (= MR2-MR1) is only specs by a min. of 1microsec. So it should not hurt at all to make it 10microsec or so (instead of just 2)
0 Kudos