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:
Sun Jan 09 19:55:59 2022 +0000
Revision:
1:d1f1c7d9fbba
Parent:
0:f8565ce9a7ca
2 MHz SPI clock frequency for the ADC chip.

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 1:d1f1c7d9fbba 61 spi.frequency(2000000); // 1 to 4 MHz recommend for the adc081s021
timo_k2 0:f8565ce9a7ca 62 // ready to wait the conversion start
timo_k2 0:f8565ce9a7ca 63 alsCS.write(1);
timo_k2 1:d1f1c7d9fbba 64 ThisThread::sleep_for(1ms);
timo_k2 0:f8565ce9a7ca 65
timo_k2 0:f8565ce9a7ca 66 while (true) {
timo_k2 0:f8565ce9a7ca 67 if(sw2.read() == 0){
timo_k2 0:f8565ce9a7ca 68 alsScaledI = getALS();
timo_k2 0:f8565ce9a7ca 69 }
timo_k2 0:f8565ce9a7ca 70 else{
timo_k2 0:f8565ce9a7ca 71 alsScaledI = getPhotoDiode();
timo_k2 0:f8565ce9a7ca 72 }
timo_k2 0:f8565ce9a7ca 73
timo_k2 0:f8565ce9a7ca 74 printf("Ambient light scaled to LUX = %0d\r\n",alsScaledI);
timo_k2 0:f8565ce9a7ca 75
timo_k2 0:f8565ce9a7ca 76 if (alsScaledI > 100){
timo_k2 0:f8565ce9a7ca 77 LED.write(1);
timo_k2 0:f8565ce9a7ca 78 printf("Light enough for working \n\n");
timo_k2 0:f8565ce9a7ca 79 }
timo_k2 0:f8565ce9a7ca 80 else{
timo_k2 0:f8565ce9a7ca 81 LED.write(0);
timo_k2 0:f8565ce9a7ca 82 printf("Too low light for working \n\n");
timo_k2 0:f8565ce9a7ca 83 }
timo_k2 0:f8565ce9a7ca 84
timo_k2 0:f8565ce9a7ca 85 ThisThread::sleep_for(3000ms);
timo_k2 0:f8565ce9a7ca 86 }
timo_k2 0:f8565ce9a7ca 87 }
timo_k2 0:f8565ce9a7ca 88
timo_k2 0:f8565ce9a7ca 89 int getALS(){
timo_k2 0:f8565ce9a7ca 90 char alsByte0 = 0; //8bit data from sensor board, char is the unsigned 8bit
timo_k2 0:f8565ce9a7ca 91 char alsByte1 = 0; // 8bit data from sensor board
timo_k2 0:f8565ce9a7ca 92 char alsByteSh0 = 0;
timo_k2 0:f8565ce9a7ca 93 char alsByteSh1 = 0;
timo_k2 0:f8565ce9a7ca 94 char als8bit = 0; // unsigned 8 bit integer value
timo_k2 0:f8565ce9a7ca 95 float alsScaledF = 0; // 32 bit floating point
timo_k2 0:f8565ce9a7ca 96
timo_k2 0:f8565ce9a7ca 97 // Begin the conversion process and serial data output
timo_k2 0:f8565ce9a7ca 98 alsCS.write(0);
timo_k2 1:d1f1c7d9fbba 99 ThisThread::sleep_for(1ms);
timo_k2 0:f8565ce9a7ca 100 // Reading two 8bit bytes by writing two dymmy 8bit bytes
timo_k2 0:f8565ce9a7ca 101 alsByte0 = spi.write(0x00);
timo_k2 0:f8565ce9a7ca 102 alsByte1 = spi.write(0x00);
timo_k2 0:f8565ce9a7ca 103 // End of serial data output and back to tracking mode
timo_k2 0:f8565ce9a7ca 104 alsCS.write(1);
timo_k2 1:d1f1c7d9fbba 105 ThisThread::sleep_for(1ms);
timo_k2 0:f8565ce9a7ca 106 // Check the http://www.ti.com/lit/ds/symlink/adc081s021.pdf
timo_k2 0:f8565ce9a7ca 107 // The data looks like 0000AAAA AAAA0000 on the alsByte0 alsByte1
timo_k2 0:f8565ce9a7ca 108 printf("alsByte0 alsByte1 in hexadecimal %X %X\r\n",alsByte0, alsByte1);
timo_k2 0:f8565ce9a7ca 109 // shifting bits to get the number out
timo_k2 0:f8565ce9a7ca 110 alsByteSh0 = alsByte0 << 4;
timo_k2 0:f8565ce9a7ca 111 alsByteSh1 = alsByte1 >> 4;
timo_k2 0:f8565ce9a7ca 112
timo_k2 0:f8565ce9a7ca 113 als8bit =( alsByteSh0 | alsByteSh1 );
timo_k2 0:f8565ce9a7ca 114 alsScaledF = (float(als8bit))*(float(6.68));
timo_k2 0:f8565ce9a7ca 115 // The value 6.68 is 64 bit double precision floating point of type double.
timo_k2 0:f8565ce9a7ca 116 // Conversions to 32 bit floating point of type float.
timo_k2 0:f8565ce9a7ca 117
timo_k2 0:f8565ce9a7ca 118 printf("Ambient light ALS sensor 8 bit 0...255 = '%d' \r\n",als8bit);
timo_k2 0:f8565ce9a7ca 119 //printf("Ambient light scaled to LUX = '%0.1f' \r\n",alsScaledF);
timo_k2 0:f8565ce9a7ca 120 //Sorry, no more float printing in OS6 !
timo_k2 0:f8565ce9a7ca 121 // But if you really need the floating point printing:
timo_k2 0:f8565ce9a7ca 122 // https://forums.mbed.com/t/hitchhikers-guide-to-printf-in-mbed-6/12492
timo_k2 0:f8565ce9a7ca 123 return (int)alsScaledF;
timo_k2 0:f8565ce9a7ca 124 }
timo_k2 0:f8565ce9a7ca 125
timo_k2 0:f8565ce9a7ca 126 int getPhotoDiode() {
timo_k2 0:f8565ce9a7ca 127 // The function for reading the analog input value from
timo_k2 0:f8565ce9a7ca 128 // the Photo Diode amplifier and scaling it to Lux value.
timo_k2 0:f8565ce9a7ca 129 AnalogIn ainPD(A0);
timo_k2 0:f8565ce9a7ca 130 unsigned short pd12bit = 0;
timo_k2 0:f8565ce9a7ca 131 float pdScaledF = 0.0;
timo_k2 0:f8565ce9a7ca 132 pd12bit = ainPD.read_u16() >>4; // leftmost 12 bits moved 4 bits to right.
timo_k2 0:f8565ce9a7ca 133 printf("Ambient light PD sensor 12 bit 0...4095 = '%d' \r\n", pd12bit);
timo_k2 0:f8565ce9a7ca 134 pdScaledF = (float(pd12bit))*(float(0.1));
timo_k2 0:f8565ce9a7ca 135 return (int)pdScaledF;
timo_k2 0:f8565ce9a7ca 136 }