Board C0135

Thomas edited this page Aug 11, 2018 · 18 revisions

"STM8S103 Relay Control Board"

The "Relay Module STM8S103", often sold as "Relay-Board 4", is a MODBUS RS485 I/O module with a STM8S103F3P6 controller. It offers 4 relays (NO, NC), 4 input terminals, and an RS485 interface. Its price is sometimes as low as $8.00, which males it an interesting board for small control applications. Some of its weaker points can also be turned into an advantage (e.g. unprotected 3.3V GPIOs on input terminals can be used as analog inputs). Next to STM8S103F3P6 breakout boards this relay board is maybe the best choice for getting started with STM8 eForth.

Note: there are two known variants: V1.00, and V1.06. This page describes the the V1.06 variant. The V1.00 variant doesn't provide UART header pads, and it's unknown if other differences exist.

The board used to be advertised as "C0135", but that moniker was abandoned. If you search "C0135", you may still find the board, and maybe this is due to this GitHub page. On the usual sourcing sites (e.g. AliExpress), search for "Relay STM8S103".

The relay board has the following characteristics:

  • STM8S103F3P6, SWIM interface on 4 pin header (pins unpopulated)
  • 3.3V internal supply voltage (not "5V" as often advertised!)
  • 8MHz crystal (which can be replaced with 16MHz, but one can also use the HSI to get full performance)
  • Unprotected inputs, two of them with analog input option
  • RS485 interface (e.g. for Modbus)
  • RX/TX with 3.3V level on unpopulated 4 pin header pads (variant V1.06)


C0135 Forth Support

The binary release contains an image for the C0135 with set of features optimized for embedded control tasks. The default configuration provides more than 3KiB of free Flash space. Special configurations provide up to 4.5KiB non volatile memory for applications.

If you're new to STM8S programming, please refer to the getting started section.

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.

Input # Terminal

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. Unless a reference voltage is available (e.g. by replacing the µC with an STM8S903F3P6, or by using one of the inputs to read a reference source), only ratiometric measurement is possible (e.g. connect a sensor element to the board's regulated 3.3V supply).

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

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:

: 5BitRol ( a -- ) \ rotate the lower 5 bits in variable "a" 
  DUP @ 2* DUP $20 AND IF 
    $1 OR 
  $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).

\ 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" 
    600 < IF $10 \ LED 
    ELSE 2       \ relay 2 e.g. "cooling"
  OUT! ; 

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

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	NRST on header J13.2
5   PA1	OSCIN crystal
6   PA2	OSCOUT crystal
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)

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).


/RE and DE are both connected to PB5, pulled high by a R21 (10k). This means that the RS485 bus is blocked in the case of (most) µC failures.

C0135 design review

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

  • The inputs are "Arduino grade", and it's not advisable to use them for applications where robustness is required. Unprotected port pins on screw terminals, and no 3.3V voltage output, calls for very careful use:

    • consider an external protection circuit
    • keep wires as short as possible
    • use the 3.3V supply from header J13 to feed your external circuit
  • The PCB space for opto-coupled relay drivers is "waste": the transistor alone would have been sufficient, and the board space could have been used for basic input protection, or at least for a better placement of µC power supply capacitors (the purpose of the 220 µF electrolytic capacitor in the µC supply is also unclear).

  • The diode-OR for RxD from header J5.3, and the RS485 transceiver is almost pointless, since the RS485 driver is controlled by PB5. On the plus side, one can connect a "TTL" 5V RS232 interface with no risk of damaging the µC.

  • The 8MHz looks crystal is nice, but for all practical tasks the accuracy of the 16MHz HSI clock is sufficient (across the full temperature range it stays within the tolerance of UARTS). If required, the crystal can be replaced by a pin header to expose PA1 and PA2.

  • This author has extensive experience with high-quality plug-type screw terminals, a cheap knock-off of which was used for the relay outputs. Compared with automotive connectors, this type of connectors is very susceptible to fretting corrosion. If you plan to use this board unattended for an extended period of time, switch high currents, or inductive loads, make sure that the contacts are not exposed to any vibrations or strain through thermal expansion, or risk the hazard of fire. If in doubt, don't use the board!

Even a simple header for the inputs (with 3.3V and GND) would have been a more appropriate choice for the advertised application. On the bright side, the inputs can be used as fast counters, as PWM outputs, or two of them (IN1 and IN2) also as analog inputs.

Other than that, the board is a very good target for experiments, and fun to work with. It's highly recommended for learning, training, and hobby purposes. Just don't use it where life or property is at risk.

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.