Skip to content

Board C0135

Thomas edited this page Jun 16, 2023 · 45 revisions

"STM8S103 Relay Control Board"

The "Relay Module STM8S103" is a RS485 MODBUS RTU I/O module based on the STM8S103F3. It has 4 relays (NO, NC), 4 direct GPIO/input/output terminals and an RS485 interface. The usual sourcing sites reliably list the board when you search for "Relay STM8S103" or "Modbus RTU 4 Way Relay Module" (it used to be listed as "C0135" but that moniker has fallen out of use). The retail price can be as low as $6.00 which makes the board very interesting for small control applications.

NOTE: V1.02 variants of this board have appeared that advertise an STM8S103 but have an incompatible NUVOTON N76E003AT20 chip in product pictures. WAVGAT confirmed that you'll receive a board with a compatible STM8Sx03F3P6 chip. Several vendors that advertised an STM8S103 but showed a NUVOTON chip failed to reply. Buyers are advised to ask the vendor first, and to take appropriate action if the offer turns out to be misleading. If you're a vendor who can guarantee a compatible product and want it listed here you can open an issue.

If you're here for MODBUS RTU: the stock firmware doesn't meet basic timing requirements and some MODBUS clients might not work (see review here). There is a dedicated GitHub project that provides an STM8 eForth based MODBUS implementation. A binary is in stm8ef-modbus releases.

image

You can download the firmware and give it a try. The firmware not only provides a MODBUS server but also a built-in command shell and a compiler. If you like it come back to this page to learn how to turn a MODBUS node into a "nano PLC" that can communicate with the MODBUS master through "holding registers"!

The Board

There are 3 known board variants: V1.00, V1.02 and V1.06. This page describes "V1.02" and "V1.06" boards. The "V1.00" board variant doesn't provide serial interface (UART) pads and it's unknown if other differences exist.

The V1.06 variant looks like this:

C0135_Text

The relay board has the following characteristics:

  • STM8S103F3P6 (sometimes STM8S003F3P6), SWIM interface on 4 pin header (pins unpopulated)
  • 12V power supply for relays, internal 3.3V supply (not "5V" as often advertised)
  • 8MHz crystal (the HSI can be used for 16MHz operation)
  • plain (unprotected) GPIOs on terminals
    • IN1 ... IN4: 3.3V I/O w/ counter/PWM option (PC6, PC7, PD2, PD3)
    • IN1 ... IN2: 3.3V analog input option (PD2, PD3)
  • RS485 interface (e.g. for MODBUS), or
  • RX/TX with 3.3V level on unpopulated 4 pin header pads (variant V1.06)

The inputs are basically unprotected 3.3V GPIOs and it's possible to use some of them as analog inputs, timer inputs or PWM outputs. Some sellers claim that the GPIOs are "3V - 30V" inputs. They are not. If you work with with 24V PLC components you may be able to use NPN sensors but be aware that if a sensor loses GND the STM8S103 is likely to be damaged (unless you use a protective circuit, e.g. a Zener-iode/resistor network).

Getting Started

For getting started set aside about $10 for the C0135 board ($6 to $8), an ST-Link V2 programmer and a "TTL serial interface". You'll also need a soldering iron and some pin headers:

Programmer TTL-Serial-Interface soldering tools or test-clips
Programmer TTL-Serial soldering-iron and pin headers test-clips

Here are some hints for your shopping list:

  • a cheap USB ST-Link-V2 dongle (about $2 - the ST-Link adapter on any STM8S/STM32 ST Discovery Board works, too)
  • a USB to "TTL" RS232 dongle, e.g. CH340 or PL2303 based ($0.50 to $0.80 - the serial interface of many Arduino boards or USB interfaces for old mobile phones should also work)
  • some single row headers and a soldering iron (basic soldering irons with heater controls for ab $5, like the one shown, are usable - digital control for $15 is better)
  • instead of soldering test clips can be used for connecting the ST-Link or the RS232 dongle to the C0135 interface pads

Keep in mind that budget delivery from China can take anywhere from 10 to 60 days, so better order now, and enjoy having it handy on the next rainy Sunday morning.

The STM8 eForth community is supportive - please open a support ticket if you have questions!

For flashing the binary under Linux or Windows please refer to Flashing the STM8 on the STM8S Programming page.

Finally, there is a page with nice photos in Indonesian that guides the reader through using the ST-Link dongle, flashing STM8 eForth and setting up a serial console.

C0135 Forth Support

If you're new to STM8S programming this is a friendly board for getting started: the STM8 eForth binary release contains an image for the C0135 that's optimized for embedded control tasks. The default configuration provides more than 3KiB of free Flash for Forth application code. Special configurations can provide up to 4.5KiB for applications.

Note that there is also a MODBUS implementation in STM8 eForth that uses the SWIMCOM image so that a Forth console works in parallel with the MODBUS RS485 or RS232 interface. For applications that require MODBUS communication the binary C135-forth.ihx in stm8ef-modbus releases can be used. With all FC handlers included it leaves more than 1K for application code. Tweaked MODBUS binaries leave more than 2K for applications.

Analog Inputs

The STM8 eForth words ADC! and ADC@ control the analog inputs: with ADC! a channel can be selected, and with ADC@ the selected channel can be converted and read.

Terminal STM8S ADC
IN1 ADC channel 4
IN2 ADC channel 3

The following code shows how to use analog inputs:

\ read the input terminal voltage
: ain  ( c -- n )  ADC! ADC@ ;
: ain1 ( -- IN1 )  4 ain ;
: ain2 ( -- IN2 )  3 ain ;

\ measure the open IN1, and print the result
ain1 . 646 ok

The reference voltage is the 3.3V regulated power supply, and the accuracy will be in the order of "%" unless ratiometric measurement is applied: by connecting a resistive sensor (e.g. an NTC) to the board's 3.3V supply the error cancels out.

An alternative might consist in replacing the µC with an STM8S903F3P6, or by using one of the inputs to read an external reference source, and do some calculations.

The ADC conversion can be noisy. That's not necessarily a bad thing since if the noise is "benign" (i.e. there is no variable offset): noise can be used to trade acquisition time for resolution by using a digital low-pass filter (the W1209 sensor code is an example - it also removes ADC digit chattering).

Digital Outputs

The word OUT! puts a binary pattern to the relay outputs. Each relay has a status LED which is controlled by the same GPIO as the relay. The outputs are assigned as follows:

OUT bit value assigned to output
0x01 relay 1
0x02 relay 2
0x04 relay 3
0x08 relay 4
0x10 right LED

Setting an output works by setting one or more bits, e.g.:

\ activate relay 1
$1 OUT!<enter> ok
\ activate relay 2 and the right LED 
$10 $2 OR OUT!<enter> ok

Digital Inputs

The standard C0135 binary doesn't contain a code for reading digital inputs but the stm8ef-modbus project provides the word IN@ for reading IN1 to IN4:

Other uses for IN1 .. IN4

The terminals IN1 to IN4 are really just exposed STM8S103 GPIOs:

Terminal STM8S GPIO
IN1 PD3, AIN4, TIM2_CH2
IN2 PD2, AIN3, [TIM2_CH3]
IN3 PC7, SPI_MISO, [TIM1_CH2]
IN4 PC6, SPI_MOSI, [TIM1_CH1]

Brackets indicate an "alternate function" (see chapter 8 in the STM8S103 datasheet OPT2, set AFR0 for TIM1_CH1/2 or AFR1 for TIM2_CH2).

Many things can be done with these GPIO, e.g,

Use cases for an SPI interface without the SPI_SCK (PC5) are somewhat limited (but that's a question of creativity).

Character I/O

The C0135 board doesn't have a 7S-LED display, but there is some support for character I/O nevertheless: the left key S2 can be read through BKEY and ?KEYB like on other supported boards. Character I/O can be very handy for background tasks.

The following code rotates a bit pattern through the relays and the LED while the key S2 is pressed using the key repetition feature:

VARIABLE bitval
: 5BitRol ( a -- ) \ rotate the lower 5 bits in variable "a" 
  DUP @ 2* DUP $20 AND IF 
    $1 OR 
  THEN 
  $1F AND SWAP ! ;

: task ( -- ) \ background task for key demo
  ?KEY IF 
    DROP bitval DUP 5BitRol @ OUT! 
  THEN ;

' task BG !
5 bitval !

5BitRol rotates the lower 5 bits of the bit pattern in the cell (variable) represented by address a. task is designed as a background task that reads the board keys and executes code if key S2 is pressed. The conditional code rotates the bit pattern in VARIABLE bitval and stores the result to the output register with OUT!. ' task BG ! activates the background task by storing the address of task to the background task variable BG. 5 bitval ! stores a pattern with 2 active bits. Press S2 to make some noise.

The example above uses just 98 bytes, which nicely demonstrates the code density of STM8 eForth code.

C0135 Example Code: Simple Zone Control

The following code demonstrates a simple zone control with values read from Ain4 at terminal IN1 (3.3V translates to 1023).

NVM
\ simple zone control with C0135 using IN1 and two relays
\ active LED indicates neutral zone 
\ e.g. heating relay1, cooling relay2 

: ain ( n -- )   \ read Ain n
  ADC! ADC@ ;
: ain1 ( -- )    \ read IN1 
  4 ain ;
: control ( -- )
  ain1 DUP 400 < IF
    DROP 1       \ relay 1 e.g. "heating" 
  ELSE 
    600 < IF $10 \ LED 
    ELSE 2       \ relay 2 e.g. "cooling"
    THEN 
  THEN 
  OUT! ; 

\ start word: initialization of control background task
: start   ( -- ) 
  [ ' control ] LITERAL BG ! ;
' start 'BOOT !
RAM

The word control switches either relay1, relay2, or the LED by comparing the input value with the constants 400 and 600. The autostart behavior defined in start makes control run in the background.

The compiled code in the example requires just 103 byte out of more than 3 KiB application Flash memory. However, "embedded control best practice" requires at least basic failure handling (cable break detection), input signal scaling (e.g. using the interpolation code from the CN2596 page), and parameter handling. The complete code for such an application fits in less than 400 bytes, leaving plenty of space for features like data logging, a user interface, or more sophisticated control algorithms.

Hardware Description

The first device came with an unprotected ROM, which is quite unusual. Using the generic CORE image, exploring the circuits connected to GPIO ports with the Forth console was easy.

The STM8S103F3 pins are connected as follows:

Pin STM	Connected to
-------------------------------------
1   PD4	LED (1:on)
2   PD5	Tx on header J5.2
3   PD6	Rx on header J5.3, diode-OR with RS485
4   NRST Reset on header J13.2
5   PA1	OSCIN crystal
6   PA2	OSCOUT crystal
7   VSS	GND
8   Vcap C
9   VDD	+3.3V  
10  PA3	Key "S2" (0:pressed) 
11  PB5	RS485 driver enable (DE-/RE, R21 10k pull-up)
12  PB4	Relay1 (0:on)
13  PC3	Relay2 (0:on)
14  PC4	Relay3 (0:on)
15  PC5	Relay4 (0:on)
16  PC6	IN4 (TIM1_CH1)
17  PC7	IN3 (TIM1_CH2)
18  PD1	SWIM on header J13.3
19  PD2	IN2 (AIN3, TIM2_CH3)
20  PD3	IN1 (AIN4, TIM2_CH2)

STM8S103F3P6

RS485 Interface

According to the datasheet the SP3485 transceiver IC has standard SN75176B features. It's specified for 3.3V supply but it's 5V tolerant, and the "absolute maximum rating" of 6V indicates that it can be operated at 5V as well (in case someone wants to modify the C0135 board to 5V operation by simply replacing the linear regulator).

SP3485

In the (not unlikely case) that you plan to use a cheap "Black-Green USB-RS485" interface on the PC side for testing there is a review on Hack-a-Day.

C0135 design review

Doing a design review with the engineer who made this board would be fun:

  • the inputs are "Arduino grade": unprotected GPIOs on screw terminals, and no 3.3V voltage output, calls for careful use:
    • consider using the 3.3V supply from header J13 to feed your external circuit and keep wires short, or
    • use "NPN sensors" and apply an external protection circuit (e.g. a 3.3V zener diode)
  • the PCB space for opto-isolated relay drivers is "waste": a transistor alone would have been sufficient.
  • the purpose of the 220 µF electrolytic capacitor in the µC supply is unclear
  • the RS485 driver's /RE and DE are both connected to PB5, pulled high by a R21 (10k). This means that the board will block the RS485 bus in the case of most µC failures (luckily the µC is very reliable!). When writing code for RS485 take care that the first thing you do after reset is pulling PB5 low.
  • the diode-OR for RxD from header J5.3, and the RS485 transceiver is pointless, since when PB5 is low the RS485 driver will block the UART anyway
  • the 8MHz crystal, instead of 16MHz, is a bit of a pity. Fortunately, the internal 16MHz HSI clock is sufficient for MODBUS (it stays within the tolerance of typical UARTS across the full temperature range ). The crystal can be replaced, or a pin header can be installed to expose the GPIOs PA1 and PA2.
  • for typical applications of a MODBUS board unprotected GPIOs on input terminals are a bit unusual - a simple header for the inputs (with 3.3V and GND) would have been a more appropriate choice. On the bright side, the "inputs terminals" can be used as fast counters, PWM outputs and for many other purposes. Two of them (IN1 and IN2) can be used as analog inputs.

The board is a very good target for experiments and fun to work with. It's highly recommended for learning, training, and hobby purposes. It certainly can be used for small embedded control applications as long as health or property don't depend on it.

Clone this wiki locally