The code is developed for the hardware NUCLEO-L432KC or any other board with SPI communication and the Digilent Pmod ALS1 ambient light sensor module. The purpose is to make students to understand the development process. They need to study the original analog to digital converter documentation to understand how the converter 16 bit output is converted to an illuminance value.

Committer:
timo_k2
Date:
Tue Sep 14 11:33:44 2021 +0000
Revision:
0:f8565ce9a7ca
Child:
1:d1f1c7d9fbba
Initial commit.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
timo_k2 0:f8565ce9a7ca 1 /* mbed Microcontroller Library
timo_k2 0:f8565ce9a7ca 2 * Copyright (c) 2019 ARM Limited
timo_k2 0:f8565ce9a7ca 3 * SPDX-License-Identifier: Apache-2.0
timo_k2 0:f8565ce9a7ca 4 ************************************************************************
timo_k2 0:f8565ce9a7ca 5 *
timo_k2 0:f8565ce9a7ca 6 * Test of the Pmod ambient light sensor
timo_k2 0:f8565ce9a7ca 7 *
timo_k2 0:f8565ce9a7ca 8 *************************************************************************
timo_k2 0:f8565ce9a7ca 9 * Description: McLab13_Sensor_SPI_PmodALS_OS6
timo_k2 0:f8565ce9a7ca 10 * The ambient light value will be read and converted to LUX.
timo_k2 0:f8565ce9a7ca 11 *
timo_k2 0:f8565ce9a7ca 12 * Material
timo_k2 0:f8565ce9a7ca 13 * 1. ST NUCLEO L432KC or NXP FRDM-K64F
timo_k2 0:f8565ce9a7ca 14 * or some other micro controller board with SPI communication
timo_k2 0:f8565ce9a7ca 15 * 2. Digilent Pmod ALS ambient light sensor
timo_k2 0:f8565ce9a7ca 16 * Please connect L432KC or FRDM-K64F - PmodALS with lines:
timo_k2 0:f8565ce9a7ca 17 * L432KC D13 - ALS 4 SCK hardware defined for the SPI
timo_k2 0:f8565ce9a7ca 18 * L432KC D12 - ALS 3 MISO hardware defined for the SPI
timo_k2 0:f8565ce9a7ca 19 * L432KC A6 - ALS 1 CS or any other free
timo_k2 0:f8565ce9a7ca 20 * GND - ALS 5 GND
timo_k2 0:f8565ce9a7ca 21 * Vcc - ALS 6 Vcc
timo_k2 0:f8565ce9a7ca 22
timo_k2 0:f8565ce9a7ca 23 * ALS data on the SPI
timo_k2 0:f8565ce9a7ca 24 * D15 ... D12 - four zeros
timo_k2 0:f8565ce9a7ca 25 * D11 ... D04 - 8 bits of ambient light data
timo_k2 0:f8565ce9a7ca 26 * D03 ... D00 - four zeros
timo_k2 0:f8565ce9a7ca 27 *
timo_k2 0:f8565ce9a7ca 28 * Details on the ADC IC on ALS board are given at
timo_k2 0:f8565ce9a7ca 29 * http://www.ti.com/lit/ds/symlink/adc081s021.pdf
timo_k2 0:f8565ce9a7ca 30 * The Pmod ALS
timo_k2 0:f8565ce9a7ca 31 * https://reference.digilentinc.com/reference/pmod/pmodals/start
timo_k2 0:f8565ce9a7ca 32 *
timo_k2 0:f8565ce9a7ca 33 ***************************************************************************
timo_k2 0:f8565ce9a7ca 34 * 3. Option A for task 2: Photo Diode BPW34 and amplifier circuit on HAMK McBoard.
timo_k2 0:f8565ce9a7ca 35 * 3. Option B for task 2: Photo Diode BPW34, OpAmp TLC721, 330k, 12 pF. Detailed
timo_k2 0:f8565ce9a7ca 36 * circuit diagram in the instruction sheet.
timo_k2 0:f8565ce9a7ca 37 *
timo_k2 0:f8565ce9a7ca 38 * Timo Karppinen 16.04.2021 copyright Apache-2.0
timo_k2 0:f8565ce9a7ca 39 *************************************************************************/
timo_k2 0:f8565ce9a7ca 40 #include "mbed.h"
timo_k2 0:f8565ce9a7ca 41
timo_k2 0:f8565ce9a7ca 42 DigitalOut LED(D2); // LD1 to LD4 pin names are linked to D13 in L432KC.
timo_k2 0:f8565ce9a7ca 43 // The L432KC board "LD3" is connected the D13. Do not use! It is the SPI SCK.
timo_k2 0:f8565ce9a7ca 44 // PmodALS
timo_k2 0:f8565ce9a7ca 45 SPI spi(D11, D12, D13); // mosi, miso, sck
timo_k2 0:f8565ce9a7ca 46
timo_k2 0:f8565ce9a7ca 47 DigitalOut alsCS(A6); // chip select for sensor SPI communication
timo_k2 0:f8565ce9a7ca 48 //DigitalIn sw2(A2); // input from switch2 on the HAMK McBoard
timo_k2 0:f8565ce9a7ca 49 // Any pin can be used with internal pull down
timo_k2 0:f8565ce9a7ca 50 DigitalIn sw2(A2, PullDown); // works OK if nothing connected to this pin.
timo_k2 0:f8565ce9a7ca 51
timo_k2 0:f8565ce9a7ca 52 int alsScaledI = 0; // 32 bit integer
timo_k2 0:f8565ce9a7ca 53 int getALS(); // function for the Digilent PmodALS sensor
timo_k2 0:f8565ce9a7ca 54 int getPhotoDiode(); // function for the photo diode circuit
timo_k2 0:f8565ce9a7ca 55
timo_k2 0:f8565ce9a7ca 56 int main(){
timo_k2 0:f8565ce9a7ca 57 // SPI for the ALS
timo_k2 0:f8565ce9a7ca 58 // Setup the spi for 8 bit data, high steady state clock,
timo_k2 0:f8565ce9a7ca 59 // second edge capture, with a 12MHz clock rate
timo_k2 0:f8565ce9a7ca 60 spi.format(8,0);
timo_k2 0:f8565ce9a7ca 61 spi.frequency(12000000);
timo_k2 0:f8565ce9a7ca 62 // ready to wait the conversion start
timo_k2 0:f8565ce9a7ca 63 alsCS.write(1);
timo_k2 0:f8565ce9a7ca 64
timo_k2 0:f8565ce9a7ca 65 while (true) {
timo_k2 0:f8565ce9a7ca 66 if(sw2.read() == 0){
timo_k2 0:f8565ce9a7ca 67 alsScaledI = getALS();
timo_k2 0:f8565ce9a7ca 68 }
timo_k2 0:f8565ce9a7ca 69 else{
timo_k2 0:f8565ce9a7ca 70 alsScaledI = getPhotoDiode();
timo_k2 0:f8565ce9a7ca 71 }
timo_k2 0:f8565ce9a7ca 72
timo_k2 0:f8565ce9a7ca 73 printf("Ambient light scaled to LUX = %0d\r\n",alsScaledI);
timo_k2 0:f8565ce9a7ca 74
timo_k2 0:f8565ce9a7ca 75 if (alsScaledI > 100){
timo_k2 0:f8565ce9a7ca 76 LED.write(1);
timo_k2 0:f8565ce9a7ca 77 printf("Light enough for working \n\n");
timo_k2 0:f8565ce9a7ca 78 }
timo_k2 0:f8565ce9a7ca 79 else{
timo_k2 0:f8565ce9a7ca 80 LED.write(0);
timo_k2 0:f8565ce9a7ca 81 printf("Too low light for working \n\n");
timo_k2 0:f8565ce9a7ca 82 }
timo_k2 0:f8565ce9a7ca 83
timo_k2 0:f8565ce9a7ca 84 ThisThread::sleep_for(3000ms);
timo_k2 0:f8565ce9a7ca 85 }
timo_k2 0:f8565ce9a7ca 86 }
timo_k2 0:f8565ce9a7ca 87
timo_k2 0:f8565ce9a7ca 88 int getALS(){
timo_k2 0:f8565ce9a7ca 89 char alsByte0 = 0; //8bit data from sensor board, char is the unsigned 8bit
timo_k2 0:f8565ce9a7ca 90 char alsByte1 = 0; // 8bit data from sensor board
timo_k2 0:f8565ce9a7ca 91 char alsByteSh0 = 0;
timo_k2 0:f8565ce9a7ca 92 char alsByteSh1 = 0;
timo_k2 0:f8565ce9a7ca 93 char als8bit = 0; // unsigned 8 bit integer value
timo_k2 0:f8565ce9a7ca 94 float alsScaledF = 0; // 32 bit floating point
timo_k2 0:f8565ce9a7ca 95
timo_k2 0:f8565ce9a7ca 96 // Begin the conversion process and serial data output
timo_k2 0:f8565ce9a7ca 97 alsCS.write(0);
timo_k2 0:f8565ce9a7ca 98 // Reading two 8bit bytes by writing two dymmy 8bit bytes
timo_k2 0:f8565ce9a7ca 99 alsByte0 = spi.write(0x00);
timo_k2 0:f8565ce9a7ca 100 alsByte1 = spi.write(0x00);
timo_k2 0:f8565ce9a7ca 101 // End of serial data output and back to tracking mode
timo_k2 0:f8565ce9a7ca 102 alsCS.write(1);
timo_k2 0:f8565ce9a7ca 103 // Check the http://www.ti.com/lit/ds/symlink/adc081s021.pdf
timo_k2 0:f8565ce9a7ca 104 // The data looks like 0000AAAA AAAA0000 on the alsByte0 alsByte1
timo_k2 0:f8565ce9a7ca 105 printf("alsByte0 alsByte1 in hexadecimal %X %X\r\n",alsByte0, alsByte1);
timo_k2 0:f8565ce9a7ca 106 // shifting bits to get the number out
timo_k2 0:f8565ce9a7ca 107 alsByteSh0 = alsByte0 << 4;
timo_k2 0:f8565ce9a7ca 108 alsByteSh1 = alsByte1 >> 4;
timo_k2 0:f8565ce9a7ca 109
timo_k2 0:f8565ce9a7ca 110 als8bit =( alsByteSh0 | alsByteSh1 );
timo_k2 0:f8565ce9a7ca 111 alsScaledF = (float(als8bit))*(float(6.68));
timo_k2 0:f8565ce9a7ca 112 // The value 6.68 is 64 bit double precision floating point of type double.
timo_k2 0:f8565ce9a7ca 113 // Conversions to 32 bit floating point of type float.
timo_k2 0:f8565ce9a7ca 114
timo_k2 0:f8565ce9a7ca 115 printf("Ambient light ALS sensor 8 bit 0...255 = '%d' \r\n",als8bit);
timo_k2 0:f8565ce9a7ca 116 //printf("Ambient light scaled to LUX = '%0.1f' \r\n",alsScaledF);
timo_k2 0:f8565ce9a7ca 117 //Sorry, no more float printing in OS6 !
timo_k2 0:f8565ce9a7ca 118 // But if you really need the floating point printing:
timo_k2 0:f8565ce9a7ca 119 // https://forums.mbed.com/t/hitchhikers-guide-to-printf-in-mbed-6/12492
timo_k2 0:f8565ce9a7ca 120 return (int)alsScaledF;
timo_k2 0:f8565ce9a7ca 121 }
timo_k2 0:f8565ce9a7ca 122
timo_k2 0:f8565ce9a7ca 123 int getPhotoDiode() {
timo_k2 0:f8565ce9a7ca 124 // The function for reading the analog input value from
timo_k2 0:f8565ce9a7ca 125 // the Photo Diode amplifier and scaling it to Lux value.
timo_k2 0:f8565ce9a7ca 126 AnalogIn ainPD(A0);
timo_k2 0:f8565ce9a7ca 127 unsigned short pd12bit = 0;
timo_k2 0:f8565ce9a7ca 128 float pdScaledF = 0.0;
timo_k2 0:f8565ce9a7ca 129 pd12bit = ainPD.read_u16() >>4; // leftmost 12 bits moved 4 bits to right.
timo_k2 0:f8565ce9a7ca 130 printf("Ambient light PD sensor 12 bit 0...4095 = '%d' \r\n", pd12bit);
timo_k2 0:f8565ce9a7ca 131 pdScaledF = (float(pd12bit))*(float(0.1));
timo_k2 0:f8565ce9a7ca 132 return (int)pdScaledF;
timo_k2 0:f8565ce9a7ca 133 }