Jan 24, 2018

Water Level Sensor of Washing Machine (STM32F103C8T6)

Washing Machine
Typical work principle of water level sensor of a washing machine shown on the picture. Sensor is located above the water level and connected by an air tight tube to the bottom of the tub. When the water level increase, the pressure in tube increase as well due to gravitational force.

The sensor convert pressure to frequency by placing an ferrite bead on a diaphragm in an inductor. The variation of inductance then converted to frequency by a chip and some passive components.
The frequency has a quite linear correlation to water level. In the curve, 26 kHz generated when water level 0mm, and 23 kHz when water level 200mm. In practice, 400mm water level will generate 20kHz.

Level vs Frequency

Level Sensor

Typically the sensor looks like the picture  at left side. There are three pins which are GND, OUT, VCC or sometimes VSS, OUT, VDD (5VDC). If you are not sure, you can check the forward voltage of the pins since there is a protection diode between VDD and VSS. When the forward is about 0.4-0.6V meaning the plus lead of multimeter is VSS and minus lead is VDD because the protection diode is installed in reverse polarity.

Two pin type sensor is not usable for this project because it contains only inductor without L to F converter. Two pin type is suitable for the system which converter located in the washing machine controller.

Complete Project
I made 10 sampling per second so the pulse count range is 2627 down to 2000. You can convert the range of reading to 0-100% or 0-400mm depending on your application. Connect a plastic tube to the sensor, blow the tube with your mouth to simulate the water level change.

You can get from the link https://drive.google.com
The code was compiled using Coocox CoIDE and GNU Tools ARM Embedded.
Anyway other compilers will do.

Nov 24, 2017

MAX7219 8-digits 7-segment (STM32F103C8T6)

I made MAX7219 for C51 but now I need it for STM32F103 too.
The wiring is simple:
MAX7219_CLK   hooked up to PORTA0,
MAX7219_DIN  to PORTA1,
MAX7219_CS    to PORTA2.

The software initiate the clock, GPIO, MAX7219 and then display is ready to use.
Just call _DisplayInt procedure and pass the value, it will display the integer on the seven segments.
If you need to turn-on the decimal point, just add 0x80 to the digit to display, example:
0x08 is the digit number, 0x80 is the command to turn on the decimal point.

Get the code here.

Oct 15, 2017

MCP4725 I2C 12-bit DAC (STM32F103C8T6)

This breakout development board can be bought easily online. The interface is I2C.
For other microcontroller, it's easy to hook up because wire.h library can handle it. For STM32F103, the example codes doesn't work. It seems the I2C interface get some error. That's the reason why I don't use I2C interface but I emulate the GPIO instead.

The code will init the GPIO, then zero the DAC and send increment count from 0 to 4095. The maximum voltage output depends on the VCC, in my case is 3.3V. In many examples found on Google, the address is before left shifted ie. 0x62 or 0x61 but in my code the address is 0xC4 because directly implemented to I2C interface. This circuit will be useful for my 4-20mA project Rev3. Using STM32F103C8T6, 7-segment display, DAC, step up DC/DC and V/I converter, Rev3 will be much easier to build.

You can get the code https://drive.google.com.
Please send me your comment to silvester.dao(_)gmail.com .

Aug 25, 2017

PLC Programmable Logic Control (STM32F103C8T6)

Project picture

I need a simple logic processing for 3 push buttons, 1 selector switch, 3 proximity switches and 2 solenoid valves. In total 7 DIs and 2 DOs. Why should I use a PLC when I can create PLC like system with my STM32F103C8T6.
Here below the logic.

The logic diagram

To get this work on a microcontroller, I create periodic timer interrupt, in this case 10,000us meaning the code is executed 100 times in a second or equals to 10ms response time.

//timer setup for 10ms interrupt is not shown in this code
void TIM1_UP_IRQHandler (void)
    if ((TIM1->SR & 0x0001) != 0) // check interrupt source
        if (timercount>=20)
        { //Blinking heartbeat LED
            GPIO_WriteBit( GPIOC, LED, (BitAction) (count & 1));
            if (count>9999) count=0;
        TIM1->SR &= ~(1<<0);  // clear UIF flag
} // end TIM1_UP_IRQHandler

And the logic is translated into C language as below:

void Cyclic_Logic (void) //executed every 10mS
    //Signal invertion is done here, Normally Open or Normally Closed
    //Inputs    (Condition)                           ? Yes:No;
    PB_Up =     (GPIO_ReadInputDataBit(GPIOA, DI0)==1)? 1:0;  //NO
    PB_Stop =   (GPIO_ReadInputDataBit(GPIOA, DI1)==1)? 1:0;  //NO
    PB_Down =   (GPIO_ReadInputDataBit(GPIOA, DI2)==1)? 1:0;  //NO
    Sw1 =       (GPIO_ReadInputDataBit(GPIOA, DI3)==1)? 1:0;  //NO
    ZS_Top =    (GPIO_ReadInputDataBit(GPIOA, DI4)==1)? 1:0;  //NO
    ZS_Middle = (GPIO_ReadInputDataBit(GPIOA, DI5)==1)? 0:1;  //NC
    ZS_Bottom = (GPIO_ReadInputDataBit(GPIOA, DI6)==1)? 0:1;  //NC

    //variable in1, in2, in3... can be eliminated if using direct reference
    //I use those for ease understanding the code only

    in1= ZS_Middle;
    in2= ZS_Bottom;
    Select1_Q= (Sw1==1)? in2 : in1;

    in1= invert(Select1_Q);
    in2= PB_Stop;
    in3= PB_Up;
    OR2_Q= in1 | in2 | in3;

    //3-RS (Reset is higher priority)
    in1= PB_Down;
    in2= OR2_Q;
    if(in1==1) RS3_Q= 1;
    if(in2==1) RS3_Q= 0;

    if (in1==1)
    if (in1==0) TOF4_ET+=10; //10msec incerement
//I put this here to give constant load to mcu
    if (TOF4_ET>=5000)

    in1 = TOF4_Q;
    Fall5_Q = ((Fall5_Prev==1) && (in1==0))? 1 : 0;

    in1= Fall5_Q;
    in2= PB_Up;
    OR6_Q =  in1|in2;

    in1= ZS_Top;
    in2= PB_Down;
    in3= PB_Stop;
    OR7_Q = in1 | in2 | in3;

    in1= OR6_Q;
    in2= OR7_Q;
    if (in1==1) RS8_Q=1;
    if (in2==1) RS8_Q=0;

    //Send the signals to output variables
    SV_Down = TOF4_Q;
    SV_Up = RS8_Q;

    //Send the output variables to Binary Outputs    
    GPIO_WriteBit( GPIOB, DO1, (BitAction) (SV_Down   &1));
    GPIO_WriteBit( GPIOB, DO0, (BitAction) (SV_Up     &1));

Since boolean type variable is not available, I use unsigned char (u8) to replace it. Invertion operation is done by byte as shown below.

u8 invert (u8 in1)
    return (~in1 & 1);

This PLC has some disadvantage:
- Variables are volatile
- Online change is not possible
- No graphical function block diagram editor
For my application this system works perfectly because it is a tiny system and no online change needed. 

Because the logic is handled by timer interrupt, main function can be used to handle serial communication with PC so you can monitor or manipulate the variable online.

Full view

Wiring diagram

Jul 2, 2017

DHT-11 Humidity and Temperature Sensor (STM32F103C8T6)

This project is to get humidity and temperature readings from DHT-11 and show them on 4-digit seven segment display TM1637.

Microcontroller pin connections are:
PORTA Pin_0 for TM1637_CLK (Display)
PORTA Pin_1 for TM1637_DIO (Display)
PORTA Pin_2 for DHT11_1Wire (Sensor)
and of course VCC and GND to every module.

You can get the code https://drive.google.com.

Nov 21, 2016

Digital Clock with DS3231, TM1637 (STM32F103C8T6)

It is really simple to do. Only 4 wires for DS3231 (the real time clock), 4 wires for TM1637 (in this case is 4 digit display), 2 wires for STM32F103C8 (32-bit microcontroller).
DS3231 wires are: VCC, GND, SCL (goes to PA.7), SDA (goes to PA.6)
TM1637 wires are: VCC, GND, CLK (goes to PA.0), DIO (goes to PA.1)
STM32F103C8 wires are: VCC and GND.
DS3231 is an extremely accurate I2C real time clock, accuracy 2ppm (at 0-40 degC) that is about a minute per year.

Digital Clock
DS3231 equipped with 3V battery to keep RTC counting when power off. There's no push buttons for time setup yet, time setup is done in the software. After running program with time setup, give comment sign (//) to the time setup line and reload program. You can get the code https://drive.google.com, compile it and download the hex to microcontroller using STLINK-V2.


Aug 2, 2016

4-Digit Seven Segment Display TM1637 (STM32F103C8T6)

TM1367 is a LED drive and keyboard scan controller but in this application it is uses for driving 4 digits seven segment display. There are 4 wires connecting the display and the microcontroller:

Display : MCU 
GND     - GND
VCC     - 5V
DIO     - Port A1
CLK     - Port A0

It communicate with I2C protocol that's why the code has below procedures:
- TM1637Start(void);
- TM1637Stop(void);
- TM1637ReadAck(void);

The example code init the mcu, init the TM1367 and then display integer counting from 0-9999 repeatedly. Get the code https://drive.google.com.

Nov 6, 2015

Multichannel 12-bit ADC with Bluetooth Link

This module read the voltage from 4 channels through gain adjustment trimmer potensiometer . Internally, ADC range is 0.0-3.3V, to make it possible to read 0.0-6.0V potentiometers are added. Then voltage input is filtered by 10nF capacitor and clamped by 3.3 V Zenner diode to protect the mcu from over voltage and reverse polarity voltage. Bluetooth module send the data serially to a remote PC (0-20m away) for data logging. Power supply module input can vary 12-24VDC and the output is stable 5.0 VDC. I need this module for monitoring a QCS (Quality Control System) sensor voltage stability. As it is scanning on paper web, I need wireless device to connect it to unmoving PC. You can use it for other purpose as well, data logging can be used for different voltage range or non-wireless communication.  Minor modification on hardware and software would fit your application.



Donate and get the code here.

Jun 21, 2015

MAX7219 driven 8-Digit 7-segmen (8051)

In old days we have to multiplex the data using time interrupt to display the right numbers to multi digit seven segment. Now we have MAX7219 to do the multiplexing job, mcu is freed from that job and we can use timer interrupt for other purpose. Mcu will access the display only when changing something similar way to controlling a LCD.

You can get example code here:
What the program does are:
- Init the seven segment
- Clear it
- Display infinite count of an integer.

ST-Link V2 to STM32F103C8T6

ST-Link V2 and the STM32 C8 on the picture are purchased from ebay seller in China. It is much easier to program the chip using this interface rather than serial interface because I don't need to touch the board to erase/download/run the program. There are only 4 wires needed ie. 3.3VCC, GND, SWDIO and SWCLK. The utility program and the USB driver seem not available anymore from ST official website, you can dig it from other place in internet. New ideas will emerge after using the ST-Link V2, I would build STM32 based PLC and I wish I have time to make it happen.

Jan 29, 2015

Digital Clock with P10 LED Module

Do you want a digital clock which can show day, date including year? The picture below shows Friday in Indonesian that is Jumat. No worries, I have changed the code into Englsh.

The time keeper is DS1302 and backup is 3 pieces 1000uF capacitor. 3 micro switches for mode, increase and decrease. C51 mcu family is used for simplicity and no high computation power is needed.

Below the PCB screenshot, well the mcu package is PLCC44 no different function with DIL40 package. The quality of crystal Q2 is very critical here because it determine the time drift. The connection to P10 LED module detail can be seen at previous post.

You can get the code here.
The apps will create the code in your phone storage in file main.txt.

Water Level Sensor of Washing Machine (STM32F103C8T6)

Washing Machine Typical work principle of water level sensor of a washing machine shown on the picture. Sensor is located above the wa...