Saturday, 13 May 2017

DS18B20 OneWire for CY8CKIT-049 PSoC

Summary
This blog utilizes a OneWire component supplied on the Cypress Forums written by Evg Pavlov to work with a Cypress CY8CKIT-049 prototyping board. The original library can be seen on Pavlov's site here. See this Cypress Thread for full details on the OneWire component and project with the Cypress Pioneer prototyping board.

Some minor changes and additions were made to the original Pioneer project. One of the changes allows the PSoC on the 049 to be returned to the bootloader mode using SW1 together with a count down timer.

OneWire Temperature Sensor (DS18B20)
The DS18B20 is a digital thermometer which communicates over a single wire bus to a micro. For this project there are the two additional wires to power the sensor. It shall be noted that OneWire devices can usually be parasitically powered meaning there are also two wire solutions being the communications / power and 0VDC power supply.

For testing of the 049 workspace the Adafruit probe MPN#381 containing the DS18B20 was used.


DS18B20 Temperature Probe
DS18B20 Temperature Probe
Cypress Forum Project
One of the projects in the forum was targeted at the CY8CKIT-042 prototyping board termed the Pioneer Kit. The PSoC on the Pioneer is a CY8C4245AXI-483. This project contained the all important OneWire example component with other components such as an LCD. The additional components from the original project could have been disabled in the schematics instead a new workspace was created for the Cypress CY8CKIT-049 prototyping board.

CY8CKIT-049 - Courtesy Cypress Semiconductor
CY8CKIT-049 - Courtesy Cypress Semiconductor
CY8CKIT-049 Project
After creating a new workspace in PSoC Creator, the OneWire component was imported from the 042 Pioneer project by selecting the Components tab in PSoC Creator, clicking the Project name and right clicking to show Import Components. The component was then located in the original project and imported.


PSoC OneWire Component
PSoC OneWire Component

A Timer component was added to the project to service the data collected from the OneWire bus, as implemented in the previous design.


Timer for Data Reporting
Timer for Data Reporting

For the 049 board it was necessary to add a bootloadable component to the project. The dependency for this bootloadable component was located in the 049 compressed Kit Setup files supplied by Cypress. For completeness the bootloader was added to the new project.


Bootloadable with UART
Bootloadable with UART

Lastly the Cypress suggested solution using the on-board switch SW1 to return the bootloadable project to the bootloader was implemented using a countdown timer. This is the relevant PSoC Creator 101 Tutorial. SW1 was also used to start the OneWire process after the 049 board had been powered by the USB, just to ensure no data was missed on power-up.


Bootloadable Reset Option
Bootloadable Reset Option
Project Software
Below is the listing for main.c from the project.



/*==============================================================================
 * Digital Thermometer demo project
 *
 * uses
 * DS18x4: MAXIM DS18B20 Digital Thermometer component (v 0.0)
 * Read temperature simultaneously from up to 8 DS18B20 sensors
 * 
 * 11/05/2017
 * Example project for CY8CKIT-049
 * Built with Creator 4.0
 * Includes timer to monitor SW1 - Resets PSoC after 2 sec, puts into bootloader
 * SW1 is also monitored to initiate the OneWire comms 
 *
 * 17/03/2018
 * Project rebuilt with updated component using Creator 4.1
 *
 * ===========================================================================================
 * PROVIDED AS-IS, NO WARRANTY OF ANY KIND, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 * FREE TO SHARE, USE AND MODIFY UNDER TERMS: CREATIVE COMMONS - SHARE ALIKE
 * ===========================================================================================
*/

#include <project.h>
//#include <stdio.h> //sprintf

/*
#if defined (__GNUC__)
    // Add an explicit reference to the floating point printf library
    // to allow the usage of floating point conversion specifiers.
    // This is not linked in by default with the newlib-nano library.
    asm (".global _printf_float");
#endif
*/

static volatile CYBIT flag_Timer = 0 ;

/* Function Prototypes */
void Initialize(void);
void ReportTemperature (void);          /* convert temperature code to deg C and send to UART */

//==============================================================================
// Timer Interrupt
//==============================================================================
CY_ISR(isr_Timer)                       /* ISR Timer to report temperature at regular intervals */
{
    flag_Timer = 1;
    isr_Timer_ClearPending();
}

//==============================================================================
// Reset PSoC Interrupt
//==============================================================================
CY_ISR (isr_Reset_Butn)                 /* Made it here then call a sw Reset */
{
    Bootloadable_Load();
}

//==============================================================================
// Init PSoC 
//==============================================================================
void Initialize(void)
{
    UART_Start();                       /* UART start */
    UART_UartPutString("Temperature sensor Maxim DS18B20:\r\n");
    OneWire_Start();                    /* OneWire start */
    Timer_1_Start();                    /* Reset button timer start */
    isr_Reset_StartEx(isr_Reset_Butn);  /* Attach handler */
    Timer_2_Start();                    /* Clock report timer start */
    isr_Timer_StartEx(isr_Timer);       /* Attach handler */  
}

//==============================================================================
// Convert temperature code to degC and 
// Send result to Terminal using UART
//==============================================================================
void ReportTemperature(void) 
{
    char strMsg[80]={0};                /* output UART buffer */
    char buf[8];                        /* temp buffer */
    static uint32 counter = 0;          /* sample counter */
    float res;
    counter++; 
   
/*
    //example using GetTemperatureAsFloat() function
    sprintf(strMsg,"%lu\t %.2f\t %.2f\t %.2f\t %.2f\t %.2f\t %.2f\t %.2f\t %.2f\r\n", 
                        counter,
                        OneWire_GetTemperatureAsFloat(0),   
                        OneWire_GetTemperatureAsFloat(1),
                        OneWire_GetTemperatureAsFloat(2),
                        OneWire_GetTemperatureAsFloat(3)    
                        OneWire_GetTemperatureAsFloat(4),   
                        OneWire_GetTemperatureAsFloat(4),
                        OneWire_GetTemperatureAsFloat(6),
                        OneWire_GetTemperatureAsFloat(7)    //25675 ticks
            );
*/
             
    strcat(strMsg, itoa10(counter, buf)); strcat(strMsg, "\t");
    strcat(strMsg, OneWire_GetTemperatureAsString(0)); strcat(strMsg, "\t");
    strcat(strMsg, OneWire_GetTemperatureAsString(1)); strcat(strMsg, "\t");
    strcat(strMsg, OneWire_GetTemperatureAsString(2)); strcat(strMsg, "\t");
    strcat(strMsg, OneWire_GetTemperatureAsString(3)); strcat(strMsg, "\t"); 
    strcat(strMsg, OneWire_GetTemperatureAsString(4)); strcat(strMsg, "\t");
    strcat(strMsg, OneWire_GetTemperatureAsString(5)); strcat(strMsg, "\t");
    strcat(strMsg, OneWire_GetTemperatureAsString(6)); strcat(strMsg, "\t");
    strcat(strMsg, OneWire_GetTemperatureAsString(7)); strcat(strMsg, "\r\n"); //1910 ticks
    UART_UartPutString(strMsg);
    
}

//==============================================================================
// Main
//==============================================================================
int main()
{
 uint8_t i;
 char c;
    
 CyGlobalIntEnable;                  /* Enable global interrupts */ 
 while(SW1_Read());                  /* Wait for button press to continue (gives you time to switch to a terminal window) */
    Initialize();
    
    flag_Timer = 1;                     /* force first measument instantly */
    
    for(;;) 
    {     
        if(flag_Timer)                  /* read DS18B20 on timer, intervals >1sec */
     {   
            flag_Timer = 0;
            OneWire_SendTemperatureRequest();                                       
        }
        
        if (OneWire_DataReady)          /* DS18 completed temperature measurement - begin read data */
     {   
            OneWire_ReadTemperature();
            ReportTemperature();
        }    
        
    }  
}


/* [] END OF FILE */

Project Hardware
Shown below is the demonstration project with the temperature sensor connected. Physical connections are detailed in the PSoC Creator project.


CY8CKIT-049 with DS18B20 Sensor
CY8CKIT-049 with DS18B20 Sensor
The output in TeraTerm is shown below.

Term Term Output
Term Term Output
PSoC Creator Project
An updated build for PSoC Creator 4.1 using new components is available below for download.


DS18x8_demo_CY8CKIT-049-42XX.Bundle01
DS18x8_demo_CY8CKIT-049-42XX.Bundle01

For legacy below is the PSoC Creator 4.0 Bundle.

DS18x8_demo_CY8CKIT-049-42XX.Bundle00.zip


Project References
Many thanks (Спасибо) once again to Pavlov for the OneWire component!