Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 09:53 16 May 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Micromite Data Logger

Author Message
cdeagle
Senior Member

Joined: 22/06/2014
Location: United States
Posts: 261
Posted: 12:50am 15 May 2015
Copy link to clipboard 
Print this post

This post describes a Micromite-based data logger. The project uses Big Mick's MuP Micromite board, a DHT22 for measuring humidity, a DS18B20 for temperature, and a Sparkfun BMP180 breakout board for logging atmospheric pressure.

The data is logged on a Sparkfun OpenLog device equipped with a 16GB micro flash card. The setup includes a RTC and all devices are powered using 3.3 volts.

The following is the source code for this data logger. The code for the BMP180 pressure sensor uses part of the code posted by TassyJim in a different thread. The data is saved approximately every minute in a comma-separated-variable (CSV) data file which includes the calendar date and local civil time for each measurement. Temperature is logged in degrees F and atmospheric pressure in inches of mercury.

option autorun on

' data_logger.bas

' May 15, 2015

' MMBasic version 4.6B

' thanks to TassyJim for the BMP code

' RTC pin-to-CPU pin wiring
' -------------------------
' SCL ==> I2C
' SCL ==> I2C

' sensor pin-to-CPU pin wiring
' ----------------------------
' DS18B20 ==> 15
' DHT22 ==> 16
' BMP180 ==> I2C

' OpenLog pin-to-CPU wiring
' -------------------------

' TXD ==> 22 (COM1: receive)
' RXD ==> 21 (COM1: transmit)

'''''''''''''''''''''''''''''

' store data from BMP180

DIM BMPData(2)

' calibration data array

DIM cal(11)

' over sampling (0 to 3)

oss = 3

' start of 11 calibration values

BMP180calMEM = &HAA

' BMP180 address

BMP180address = &H77

' BMP180 control register

BMP180control = &HF4

' BMP180 temperature command

BMP180temp = &H2E

' BMP180 pressure command

BMP180pres = &H34

' adjust command for oversampling

BMP180pres = BMP180pres + oss*&H40

' register for results of reading

BMP180reading = &HF6

' enable I2C. use slow speeds for long leads

I2C OPEN 400, 200

' extract calibration constants

z = calibrate_bmp180()

open "COM1:9600" as #5

' initial five second pause

pause 5000

do

' extract current epoch from RTC

rtc gettime

hours = val(left$(time$, 2))

minutes = val(mid$(time$, 4, 2))

seconds = val(right$(time$, 2))

time_hrs = hours + minutes / 60.0 + seconds / 3600.0

' format date in mm/dd/yyyy form

wrk_month$ = mid$(date$, 4, 2)

wrk_day$ = left$(date$, 2)

wrk_year$ = right$(date$, 4)

usa_date$ = wrk_month$ + "-" + wrk_day$ + "-" + wrk_year$

' temperature (pin 15)

temp_c = ds18b20(15)

temp_f = 1.8 * temp_c + 32.0

' humidity (pin 16)

dht22 16, temp, humidity

' atmospheric pressure

atmos = pressure(oss)

' print current data

print #5, usa_date$; ", "; time$; ","; time_hrs; ","; temp_f; ","; humidity; ","; atmos

'print usa_date$; ","; time$; ","; time_hrs; ","; temp_f; ","; humidity; ","; atmos

' pause 60 seconds between measurements

pause 60000

loop

close #5

end

'''''''''''''''''''''''''

FUNCTION calibrate_bmp180()

' extract bmp180 calibration constants

LOCAL n, calMEM

calMEM= BMP180calMEM

FOR n = 1 TO 11

' first calibration location

I2C WRITE BMP180address, 0, 1, calMEM

PAUSE 1

I2C READ BMP180address, 0, 2, BMPData(0)

cal(n) = BMPData(0)*256 + BMPData(1)

IF (n < 4 OR n > 6) THEN

' need to convert some to signed numbers

IF (cal(n) > 32767) THEN

cal(n) = cal(n) - 65536

ENDIF

ENDIF

PAUSE 1

' advance to the next calibration location

calMEM = calMEM + 2

NEXT n

END FUNCTION

''''''''''''''''''''

FUNCTION pressure(oss)

' atmospheric pressure in inches of mercury

LOCAL UT, UP, x1, x2, x3, b5, b6, b7, pres, p

pres = BMP180pres + oss * &H40

I2C WRITE BMP180address, 0, 2, BMP180control, BMP180temp

PAUSE 5

I2C WRITE BMP180address, 0, 1, BMP180reading

I2C READ BMP180address, 0, 2, BMPData(0)

UT = BMPData(0) * 256 + BMPData(1)

I2C WRITE BMP180address, 0, 2, BMP180control, pres

' different oversampling requires different reading times

IF (oss = 0) THEN

' ulta low power

PAUSE 5

ELSEIF (oss = 1) THEN

' standard

PAUSE 8

ELSEIF (oss = 2) THEN

' high resolution

PAUSE 14

ELSE

' ulta high resolution

PAUSE 26

ENDIF

I2C WRITE BMP180address, 0, 1, BMP180reading

I2C READ BMP180address, 0, 2, BMPData(0)

UP = BMPData(0) * 256 + BMPData(1)

I2C WRITE BMP180address, 0, 1, BMP180reading+2

I2C READ BMP180address, 0, 1, BMPData(0)

UP = (UP * 256 + BMPData(0)) / 2^(8 - oss)

' calculate true temperature

x1 = INT((UT - cal(6)) * cal(5) / 32768)

x2 = INT(cal(10) * 2048 / (x1 + cal(11)))

b5 = x1 + x2

t = INT((b5 + 8) / 16) / 10

' calculate true atmospheric pressure

b6 = b5 - 4000

x1 = INT((cal(8) * (b6 * b6 / 4096)) / 2048)
x2 = INT(cal(2) * b6 / 2048)
x3 = x1 + x2

b3 = INT(((cal(1) * 4 + x3) * 2^oss + 2) / 4)

x1 = INT(cal(3) * b6 / 8192)
x2 = INT((cal(7) * (b6 * b6 / 4096)) / 65536)
x3 = INT(((x1 + x2) + 2) / 4)

b4 = INT(cal(4) * x3 / 32768 + cal(4))
b7 = INT((UP - b3) * (50000 / 2^oss))

p = INT((b7 * 2) / b4)

x1 = INT(INT(p / 256) * INT(p / 256))
x1 = INT((x1 * 3038) / 65536)
x2 = INT((-7357 * p) / 65536)

pressure = 0.01 * INT(p + (x1 + x2 + 3791) / 16) / 33.86388158

END FUNCTION


The following is a picture of the data logger. The 3.3 volt power supply, sensors and OpenLog are located on the large breadboard. From left to right; the DHT22, the DS18B0, the RTC, the BMP180 and the OpenLog device.

A USB-to-TTL interface is located on the bottom left and Big Mick's MuP board is on the bottom right.


 
viscomjim
Guru

Joined: 08/01/2014
Location: United States
Posts: 925
Posted: 05:30am 15 May 2015
Copy link to clipboard 
Print this post

cdeagle, this is great stuff. I am glad to see another great project (including code)! What are your plans with this? Are you going to put it in an enclosure and use it for something specific? What are you doing with the data on the sd card, excel or something like that? Again, great work!!!!
 
cdeagle
Senior Member

Joined: 22/06/2014
Location: United States
Posts: 261
Posted: 07:12am 15 May 2015
Copy link to clipboard 
Print this post

Thanks for the positive feedback.

Eventually I plan to put the prototype in an enclosure so that I can monitor the dynamic outside weather we have here on the Space Coast of Florida. Hopefully no hurricanes this year! And perhaps add additional sensors.

I have an SD card reader that I use to download the CSV data files. I then plot the different data items as a function of time using a program called Grapher. I stop the program from running with a control-C. The use of the MMBasic OPTION autorun ON command starts a new log each time power is re-applied.

Here's an excerpt from a typical data file. Column 1 is the calendar date, column 2 is the local civil time, column 3 is the elapsed time since midnight in hours, column 4 is the temperature in degrees F, column 5 is the relative humidity and the last column is the barometric pressure in inches of mercury. This data is relatively "stable" because it was measured inside my house. Of course, the outside data should show more variations.

05-14-2015, 15:55:14, 15.9206, 78.8, 50.8, 30.2104
05-14-2015, 15:55:45, 15.9292, 78.8, 52.1, 30.2127
05-14-2015, 15:56:15, 15.9375, 78.8, 52, 30.2095
05-14-2015, 15:56:46, 15.9458, 78.8, 52, 30.2101
05-14-2015, 15:57:15, 15.9542, 78.8, 52, 30.2086
05-14-2015, 15:57:46, 15.9628, 78.8, 51.9, 30.213
05-14-2015, 15:58:16, 15.9711, 78.8, 51.8, 30.2112
05-14-2015, 15:58:47, 15.9794, 78.8, 51.7, 30.2098
05-14-2015, 15:59:16, 15.9878, 78.8, 51.9, 30.2098
05-14-2015, 15:59:46, 15.9961, 78.8, 51.8, 30.2098
05-14-2015, 16:00:17, 16.0047, 78.8, 52, 30.2083

I'll post some plots later.
 
OA47

Guru

Joined: 11/04/2012
Location: Australia
Posts: 911
Posted: 08:28pm 15 May 2015
Copy link to clipboard 
Print this post

cdeagle, can you explain why you are not using the DHT22 to read the temp?

GM
 
cdeagle
Senior Member

Joined: 22/06/2014
Location: United States
Posts: 261
Posted: 11:41pm 15 May 2015
Copy link to clipboard 
Print this post

Hi Graeme,

The main reason for using the DS18B20 sensor is the fact that I plan to eventually use a waterproof version of the sensor for outside data logging.

The DS18B20 also has a wider temperature measurement range (-55 C to 125 C) than the DHT22 (-40 C to 80 C). The DS18B20 has a default 12 bit temperature resolution (0.0625 deg C) while the DHT22 has a resolution of 0.1 deg C.

Hope this answers your question.

 
viscomjim
Guru

Joined: 08/01/2014
Location: United States
Posts: 925
Posted: 12:05am 16 May 2015
Copy link to clipboard 
Print this post

cdeagle, Holy Smokes... another person in the state of Florida that uses the uMite. What are the odds... I wonder if there are more of us. I'm in the St. Pete, Clearwater area on the west coast. Where are you?
 
cdeagle
Senior Member

Joined: 22/06/2014
Location: United States
Posts: 261
Posted: 12:22am 16 May 2015
Copy link to clipboard 
Print this post

Hi Jim,

I'm in Cape Canaveral on the east coast.
 
viscomjim
Guru

Joined: 08/01/2014
Location: United States
Posts: 925
Posted: 12:26am 16 May 2015
Copy link to clipboard 
Print this post

And your up early on a Saturday morning also.
 
cdeagle
Senior Member

Joined: 22/06/2014
Location: United States
Posts: 261
Posted: 12:30am 16 May 2015
Copy link to clipboard 
Print this post

Up at 5 am every morning. Old (sleeping) habits are hard to break!
 
cdeagle
Senior Member

Joined: 22/06/2014
Location: United States
Posts: 261
Posted: 07:57am 16 May 2015
Copy link to clipboard 
Print this post

Here are several plots created using data from the data logger. They illustrate outdoor atmospheric conditions yesterday, May 15, 2015, at Cape Canaveral, Florida.

It was an overcast day with rain showers several times during the day.









 
cdeagle
Senior Member

Joined: 22/06/2014
Location: United States
Posts: 261
Posted: 07:58am 22 May 2015
Copy link to clipboard 
Print this post

Here's a version of the source code which includes the BH1750 ambient light sensor.

Thanks to TassyJim for the BH1750 source code.

option autorun on

' data_logger.bas

' May 22, 2015

' MMBasic version 4.6B

' thanks to TassyJim for the BMP and BH1750 code

' RTC pin-to-CPU pin wiring
' -------------------------
' SCL ==> I2C
' SCL ==> I2C

' sensor pin-to-CPU pin wiring
' ----------------------------
' DS18B20 ==> 15
' DHT22 ==> 16
' BMP180 ==> I2C
' BH1750 ==> I2C

' OpenLog pin-to-CPU wiring
' -------------------------

' TXD ==> 22 (COM1: receive)
' RXD ==> 21 (COM1: transmit)

'''''''''''''''''''''''''''''

' ----------------
' setup for BMP180
' ----------------

' store data from BMP180

DIM BMPData(2)

' calibration data array

DIM cal(11)

' over sampling (0 to 3)

oss = 3

' start of 11 calibration values

BMP180calMEM = &HAA

' BMP180 address

BMP180address = &H77

' BMP180 control register

BMP180control = &HF4

' BMP180 temperature command

BMP180temp = &H2E

' BMP180 pressure command

BMP180pres = &H34

' adjust command for oversampling

BMP180pres = BMP180pres + oss*&H40

' register for results of reading

BMP180reading = &HF6

' enable I2C. use slow speeds for long leads

I2C OPEN 400, 200

' extract calibration constants

z = calibrate_bmp180()

' ----------------
' setup for BH1750
' ----------------

Dim LightData(2)

' BH1750 address

BH1750address = &H23

' open comm port

open "COM1:9600" as #5

' initial five second pause

pause 5000

do

' extract current epoch from RTC

rtc gettime

hours = val(left$(time$, 2))

minutes = val(mid$(time$, 4, 2))

seconds = val(right$(time$, 2))

time_hrs = hours + minutes / 60.0 + seconds / 3600.0

' format date in mm/dd/yyyy form

wrk_month$ = mid$(date$, 4, 2)

wrk_day$ = left$(date$, 2)

wrk_year$ = right$(date$, 4)

usa_date$ = wrk_month$ + "-" + wrk_day$ + "-" + wrk_year$

' temperature (pin 15)

temp_c = ds18b20(15)

temp_f = 1.8 * temp_c + 32.0

' humidity (pin 16)

dht22 16, temp, humidity

' atmospheric pressure

atmos = pressure(oss)

' ambient light

light = lux()

' print current data

print #5, usa_date$; ", "; time$; ","; time_hrs; ","; temp_f; ","; humidity; ","; atmos; ","; light

' uncomment this line to send data to the screen

' print usa_date$; ","; time$; ","; time_hrs; ","; temp_f; ","; humidity; ","; atmos; ","; light

' pause 60 seconds between measurements

pause 60000

loop

close #5

end

'''''''''''''''''''''''''

FUNCTION calibrate_bmp180()

' extract bmp180 calibration constants

LOCAL n, calMEM

calMEM= BMP180calMEM

FOR n = 1 TO 11

' first calibration location

I2C WRITE BMP180address, 0, 1, calMEM

PAUSE 1

I2C READ BMP180address, 0, 2, BMPData(0)

cal(n) = BMPData(0)*256 + BMPData(1)

IF (n < 4 OR n > 6) THEN

' need to convert some to signed numbers

IF (cal(n) > 32767) THEN

cal(n) = cal(n) - 65536

ENDIF

ENDIF

PAUSE 1

' advance to the next calibration location

calMEM = calMEM + 2

NEXT n

END FUNCTION

''''''''''''''''''''

FUNCTION pressure(oss)

' atmospheric pressure in inches of mercury

LOCAL UT, UP, x1, x2, x3, b5, b6, b7, pres, p

pres = BMP180pres + oss * &H40

I2C WRITE BMP180address, 0, 2, BMP180control, BMP180temp

PAUSE 5

I2C WRITE BMP180address, 0, 1, BMP180reading

I2C READ BMP180address, 0, 2, BMPData(0)

UT = BMPData(0) * 256 + BMPData(1)

I2C WRITE BMP180address, 0, 2, BMP180control, pres

' different oversampling requires different reading times

IF (oss = 0) THEN

' ulta low power

PAUSE 5

ELSEIF (oss = 1) THEN

' standard

PAUSE 8

ELSEIF (oss = 2) THEN

' high resolution

PAUSE 14

ELSE

' ulta high resolution

PAUSE 26

ENDIF

I2C WRITE BMP180address, 0, 1, BMP180reading

I2C READ BMP180address, 0, 2, BMPData(0)

UP = BMPData(0) * 256 + BMPData(1)

I2C WRITE BMP180address, 0, 1, BMP180reading+2

I2C READ BMP180address, 0, 1, BMPData(0)

UP = (UP * 256 + BMPData(0)) / 2^(8 - oss)

' calculate true temperature

x1 = INT((UT - cal(6)) * cal(5) / 32768)

x2 = INT(cal(10) * 2048 / (x1 + cal(11)))

b5 = x1 + x2

t = INT((b5 + 8) / 16) / 10

' calculate true atmospheric pressure

b6 = b5 - 4000

x1 = INT((cal(8) * (b6 * b6 / 4096)) / 2048)
x2 = INT(cal(2) * b6 / 2048)
x3 = x1 + x2

b3 = INT(((cal(1) * 4 + x3) * 2^oss + 2) / 4)

x1 = INT(cal(3) * b6 / 8192)
x2 = INT((cal(7) * (b6 * b6 / 4096)) / 65536)
x3 = INT(((x1 + x2) + 2) / 4)

b4 = INT(cal(4) * x3 / 32768 + cal(4))
b7 = INT((UP - b3) * (50000 / 2^oss))

p = INT((b7 * 2) / b4)

x1 = INT(INT(p / 256) * INT(p / 256))
x1 = INT((x1 * 3038) / 65536)
x2 = INT((-7357 * p) / 65536)

pressure = 0.01 * INT(p + (x1 + x2 + 3791) / 16) / 33.86388158

END FUNCTION

''''''''''''

function lux()

' read ambient light data from BH1750

' power on

I2C write BH1750address, 0, 1, &H01

pause 50

' 1 lx scaling, single reading (H-resolution mode)

I2C write BH1750address, 0, 1, &H20

pause 150

I2C Read BH1750address, 0, 2, LightData(0)

lux = (LightData(0) * 256.0 + LightData(1)) / 1.2

end function

 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024