-
Notifications
You must be signed in to change notification settings - Fork 66
Board C0135
The "Relay Module STM8S103" is a RS485 MODBUS RTU I/O module based on the STM8S103F3P6 (sometimes STM8S003F3P6). It offers 4 relays (NO, NC), 4 input terminals, and an RS485 interface. The input terminals are connected to unprotected 3.3V GPIOs, two of which can be used as analog inputs, timer inputs or, e.g., PWM outputs. The retail price can be as low as $8.00 which makes it an interesting board for small control applications.
Note1: The stock firmware MODBUS server implementation doesn't meet basic timing requirements and some MODBUS clients might not work (see analysis here). A Forth based MODBUS server implementation that allows for many new applications is WIP (discussion and code see Issue #238).
Note2: there are two known board variants: V1.00, and V1.06. This page describes V1.06 boards. V1.00 boards variant don't provide pads for a UART header, which is a clear disadvantage, and it's unknown if other differences exist.
The board used to be advertised as "C0135", but that moniker has since been abandoned. The usual sourcing sites (e.g. AliExpress) quite reliably list the board when you search for "Relay STM8S103".
The relay board has the following characteristics:
- STM8S103F3P6, SWIM interface on 4 pin header (pins unpopulated)
- 12V power supply for relays, 3.3V internal supply voltage (not "5V" as often advertised!)
- 8MHz crystal (the HSI can be used for 16MHz operation)
- unprotected GPIOs on terminals, two of them with analog input, two with counter/PWM option
- RS485 interface (e.g. for MODBUS), or
- RX/TX with 3.3V level on unpopulated 4 pin header pads (variant V1.06)
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 for Forth application code. Special configurations can provide up to 4.5KiB for applications.
If you're new to STM8S programming this is a friendly board for getting started). There are ongoing experiments with MODBUS).
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 |
---|---|
AIN4 | IN1 |
AIN3 | IN2 |
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).
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
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.
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.
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)
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.
Doing a design review with the engineer who made this board would be fun:
-
The inputs are "Arduino grade". Unprotected port pins on screw terminals, and no 3.3V voltage output, calls for careful use:
- apply an external protection circuit
- keep wires short
- consider using the 3.3V supply from header J13 to feed your external circuit
-
The PCB space for opto-isolated relay drivers is "waste": a transistor alone would have been sufficient, and the board space could have been better used for basic input protection
-
purpose of the 220 µF electrolytic capacitor in the µC supply is 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 crystal 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 quite 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 can be used as fast counters, as PWM outputs, or two of them (IN1 and IN2) 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 but obviously not for applications where life or property are at stake.