Justin Jordan
Published © MIT

1-Wire Wing Data Logger w/MAX32630FTHR

Add 1-Wire to your Feather based projects using the MAX32630FTHR, or my 1-Wire Wing with other Feathers.

BeginnerProtip30 minutes2,815
1-Wire Wing Data Logger w/MAX32630FTHR

Things used in this project

Hardware components

MAX32630FTHR
Maxim Integrated MAX32630FTHR
×1
Maxim Integrated DS1402D-DR8
×1
Custom fabricated PCB
OSH Park Custom fabricated PCB
×1
Maxim Integrated DS1920 iButton Temperature Sensor
×1
DS18B20 Programmable Resolution 1-Wire Digital Thermometer
Maxim Integrated DS18B20 Programmable Resolution 1-Wire Digital Thermometer
×1
Adafruit Lithium Ion Polymer Battery 3.7V 500mAh
×1
Adafruit High Temp Waterproof DS18B20 probe
×1

Software apps and online services

MACROFAB
mbed.org

Story

Read more

Schematics

1-Wire Wing Schematic

Code

MAX32630FTHR_iButton_uSD_Logger

C/C++
Program demonstrating the use of the MAX32630FTHR and my 1-Wire Wing as a data logger for iButtons, or any other sensors, that do not have internal NV memory.
/******************************************************************************
* MIT License
*
* Copyright (c) 2017 Justin J. Jordan
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
 
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
 
 
#include "mbed.h"
#include "OneWire.h"
#include "max32630fthr.h"
#include "SDFileSystem.h"
#include "Sharp_LS012B7DD01.h"
 
using namespace OneWire;
using namespace RomCommands;
 
uint8_t printMessage(SharpLS012B7DD01 &lcd, const char * msg, uint8_t ln);
uint8_t printRomId(SharpLS012B7DD01 &lcd, RomId &romId, uint8_t ln);
 
 
Ticker oneSecondTicker;
volatile uint32_t secondCounter = 0;
void oneSecond()
{
    secondCounter++;
}
 
//Setup start/stop button
DigitalIn sw2(P2_3, PullUp);
InterruptIn startStopLog(P2_3);
volatile bool startLog = false;
void startStopLogISR()
{
    startLog = !startLog;
}
 
 
int main ()
{
    //Init board and set GPIO to 3.3V logic
    MAX32630FTHR pegasus;
    pegasus.init(MAX32630FTHR::VIO_3V3);
    
    
    //Turn RGB LED off
    DigitalOut rLED(LED1, LED_ON);
    DigitalOut gLED(LED2, LED_OFF);
    DigitalOut bLED(LED3, LED_OFF);
    
    
    //Get LCD instance
    SPI spiBus(P5_1, P5_2, P5_0);
    SharpLS012B7DD01 lcd(P5_3, P5_4, P5_5, spiBus);
    printMessage(lcd, "Starting...", 0);
    wait(2.0);
    lcd.clear_display();
    
    
    //Get 1-Wire Master (owm) instance
    #if defined(TARGET_MAX32630FTHR)
        MCU_OWM owm(true, true);
    #else //some other FTHR on mbed?
        //Replace with appropriate pin names for your FTHR
        I2C i2cBus(P3_4, P3_5); 
        DS2484 owm(i2cBus);
    #endif
    
    //Make sure owm is initialized
    OneWireMaster::CmdResult result = owm.OWInitMaster();
    while(result != OneWireMaster::Success)
    {
        printMessage(lcd, "Failed to init OWM...", 0);
        result = owm.OWInitMaster();
        wait(0.5);
    }
    lcd.clear_display();
    printMessage(lcd, "OWM Initialized...", 0);
    wait(2.0);
    lcd.clear_display();
    
    
    //Check for DS1920 iButton
    SearchState search_state;
    search_state.findFamily(0x10);
    do
    {
        result = OWNext(owm, search_state);
        if(search_state.romId.familyCode() != 0x10)
        {
            printMessage(lcd, "Failed to find DS1920...", 0);
            printMessage(lcd, "Please connect DS1920...", 1);
            wait(0.5);
        }
        else
        {
            lcd.clear_display();
            printMessage(lcd, "Found DS1920...", 0);
            printRomId(lcd, search_state.romId, 1);
            wait(2.0);
            lcd.clear_display();
        }
    }
    while(search_state.romId.familyCode() != 0x10);
    
    //Get instance of DS1920 object
    MultidropRomIterator selector(owm);
    DS1920 tempSensor(selector);
    tempSensor.setRomId(search_state.romId);
    
    
    //Get instance of sd card file system
    SDFileSystem sd(P0_5, P0_6, P0_4, P0_7, "sd");  // mosi, miso, sclk, cs
    
    //Configure pin for sd card detect
    DigitalIn uSDdetect(P2_2, PullUp);
    
    static const char FILE_NAME[] = "/sd/log.txt";
    FILE *fp;
    
    //Check for card
    if(uSDdetect)
    {
        printMessage(lcd, "Please insert uSD card", 0);
        while(uSDdetect);
    }
    lcd.clear_display();
    
    rLED = LED_ON;
    gLED = LED_ON;
    do
    {
        fp = fopen(FILE_NAME, "w");
        if(fp != NULL)
        {
            lcd.clear_display();
            printMessage(lcd, "Card detected...", 0);
            printMessage(lcd, "Preparing log file...", 1);
            fprintf(fp, "Time-Stamp, Battery Voltage, Temperature\n");
            fclose(fp);
        }
        else
        {
            lcd.clear_display();
            printMessage(lcd, "Failed to open file...", 0);
            printMessage(lcd, "Press Reset Button...", 1);
            wait(2.0);
        }
    }
    while(fp == NULL);
    rLED = LED_OFF;
    gLED = LED_ON;
    wait(2.0);
    lcd.clear_display();
    
    
    enum UiStates
    {
        Reset,
        NoLog_NoCardDetected,
        NoLog_CardDetected,
        Log_NoCardDetected,
        Log_CardDetected
    };
 
    UiStates currentState = Reset, oldState = Reset;
    
    static const uint32_t SAMPLE_INTERVAL = 5; // In seconds
    bool firstSampleTaken = false;
    uint32_t sampleTime = 0;
    float batteryVoltage, temperature;
    
    //attach timer to callback for 1 second tick
    oneSecondTicker.attach(&oneSecond, 1);
    
    //Tie SW2 to callback fx
    startStopLog.fall(&startStopLogISR);
    
 
    while(1)
    {
        //card detect is active low
        //Determine state, house keeping
        if(!startLog && uSDdetect) //False, False
        {
            currentState = NoLog_NoCardDetected;
            secondCounter = 0;
            sampleTime = 0;
            firstSampleTaken = false;
        }
        else if(!startLog && !uSDdetect) //False, True
        {
            currentState = NoLog_CardDetected;
            secondCounter = 0;
            sampleTime = 0;
            firstSampleTaken = false;
        }
        else if(startLog && uSDdetect) //True, False
        {
            currentState = Log_NoCardDetected;
            secondCounter = 0;
            sampleTime = 0;
            firstSampleTaken = false;
        }
        else //True, True
        {
            currentState = Log_CardDetected;
            
            //get t = 0 sample
            if(!firstSampleTaken)
            {
                firstSampleTaken = true;
                lcd.clear_display();
                oldState = currentState;
                
                printMessage(lcd, "Logging Data...", 0);
                pegasus.getBatteryVoltage(&batteryVoltage);
                tempSensor.convertTemperature(temperature);
                
                rLED = LED_ON;
                fp = fopen(FILE_NAME, "a");
                if(fp != NULL)
                {
                    fprintf(fp, "%d, %f, %f\n", sampleTime, batteryVoltage, temperature);
                    fclose(fp);
                }
                else
                {
                    lcd.clear_display();
                    printMessage(lcd, "Failed to open file", 0);
                    printMessage(lcd, "Press Reset Button...", 1);
                    printMessage(lcd, "MBED DIE!!...", 2);
                    mbed_die();
                }
                rLED = LED_OFF;
            }
        }
        
        //If state has changed, clear dispaly
        if(oldState != currentState)
        {
            lcd.clear_display();
            oldState = currentState;
        }
        
        //State based actions
        switch(currentState)
        {
            case NoLog_NoCardDetected:
                printMessage(lcd, "Please insert uSD card...", 0);
            break;
            
            case NoLog_CardDetected:
                printMessage(lcd, "Press SW2 to start logging", 0);
                printMessage(lcd, "data...", 1);
            break;
            
            case Log_NoCardDetected:
                startLog = false;
                printMessage(lcd, "Please insert uSD card", 0);
            break;
            
            case Log_CardDetected:
            
                if(secondCounter >= SAMPLE_INTERVAL)
                {
                    secondCounter = 0;
                    sampleTime += SAMPLE_INTERVAL;
                    
                    printMessage(lcd, "Logging Data...", 0);
                    pegasus.getBatteryVoltage(&batteryVoltage);
                    tempSensor.convertTemperature(temperature);
                    
                    rLED = LED_ON;
                    fp = fopen(FILE_NAME, "a");
                    if(fp != NULL)
                    {
                        fprintf(fp, "%d, %f, %f\n", sampleTime, batteryVoltage, temperature);
                        fclose(fp);
                    }
                    else
                    {
                        lcd.clear_display();
                        printMessage(lcd, "Failed to open file", 0);
                        printMessage(lcd, "Press Reset Button...", 1);
                        printMessage(lcd, "MBED DIE!!...", 2);
                        mbed_die();
                    }
                    rLED = LED_OFF;
                }
                
            break;
            
            default:
                lcd.clear_display();
                printMessage(lcd, "Bad State...", 0);
                printMessage(lcd, "Press Reset Button...", 1);
                printMessage(lcd, "MBED DIE!!...", 2);
                mbed_die();
            break;
        }
    }    
}
 
 
//*********************************************************************
uint8_t printMessage(SharpLS012B7DD01 &lcd, const char * msg, uint8_t ln)
{
    char temp_buff[31];
    uint8_t buf_idx = 0;
    temp_buff[buf_idx++] = '>';
    temp_buff[buf_idx++] = '>';
    for(; buf_idx < 30; buf_idx++)
    {
        temp_buff[buf_idx] = ' ';
    }
    buf_idx = 2;
    
    if(strlen(msg) <= 28)
    {
        memcpy((temp_buff + buf_idx), msg, strlen(msg));
        temp_buff[buf_idx + strlen(msg)] = NULL;
    
        if(ln > 3)
        {
            lcd.clear_display();
            ln = 0;
        }
        lcd.print_str(ln++, 0, temp_buff);
    }
    return ln;
}
 
 
//*********************************************************************
uint8_t printRomId(SharpLS012B7DD01 &lcd, RomId &romId, uint8_t ln)
{
    int8_t idx = 7;
    uint8_t temp_hi, temp_lo;
    
    char temp_buff[31];
    uint8_t buf_idx = 0;
    temp_buff[buf_idx++] = '>';
    temp_buff[buf_idx++] = '>';
    for(; buf_idx < 30; buf_idx++)
    {
        temp_buff[buf_idx] = ' ';
    }
    buf_idx = 2;
    
    do
    {
        
        temp_hi = ((romId.buffer[idx] & 0xF0) >> 4);
        temp_lo = (romId.buffer[idx--] & 0x0F);
        
        //get high nib in ascii
        if(temp_hi < 10)
        {
            temp_buff[buf_idx++] = (temp_hi + 0x30);
        }
        else
        {
            temp_buff[buf_idx++] = ((temp_hi - 10) + 0x41);
        }
        
        //get low nib in ascii
        if(temp_lo < 10)
        {
            temp_buff[buf_idx++] = (temp_lo + 0x30);
        }
        else
        {
            temp_buff[buf_idx++] = ((temp_lo - 10) + 0x41);
        }
        
        temp_buff[buf_idx++] = ' ';
    }
    while(idx >= 0);
    temp_buff[buf_idx++] = NULL;
    
    if(ln > 3)
    {
        lcd.clear_display();
        ln = 0;
    }
    lcd.print_str(ln++, 0, temp_buff);
    
    return ln;
}
 

Credits

Justin Jordan

Justin Jordan

2 projects • 2 followers
Industrial technician turned engineer.

Comments