Weact CH32X035 Board and Serial Monitor

Has anyone else tried using the Weact CH32X035 board? I'm interested in using it for its USB-PD sink abilities. However, while I can program it and get a blinky to work, I cannot seem to send to find a way to send output to the serial monitor. The board is connected via a WCH Link-E programmer.

If anyone else has this board, and can give me some clue as to how to get output to the serial monitor, I'd be grateful. Thanks.

I don't have this board but I expect that after a Serial.begin(...) the onboard USB connector should show up as a serial port.

Here is some example code where you can seen how to use the Serial port:
DigitalReadSerial.ino

Does it show up as unknown device in the device manager?

No, after Serial.begin(...), not data appears in the serial monitor when I do Serial. println(...). It's an issue specific to this board.

Does anyone have an offical WCH CH32X035 board? And if so, do you get output on the serial monitor? Did you have to do anything special to get it?

I have the WeAct board. CDC is not ported (yet) to CH32X035. When you look at the "issue" list on github you'll find a patchset from september that enables TinyUSB for the board, but AFAICT the code in the Adafruit library is not yet complete --> you get a bunch of errors - I did not have the time to trace that.

For USB-PD only (without CDC) you'll need WCH arduino core "main" branch and not "1.0.4".

I just remember that GitHub - wagiminator/CH32X033-USB-NRF: USB controlled nRF24L01+ 2.4GHz Transceiver builds a CDC device with ch32x035, so this is probably a good starting point.

Thanks. I already have the USB-PD working (without printf).
However, I'm not at this stage trying to use the CH32x035's USB port for serial - I am using the wch-link-e programmer to upload the sketch, and that is where I want my serial output to go...

Hi @ralphrmartin. The WCH-Link programmers have RX and TX pins, and act as a USB to serial bridge adapter in addition to the primary function as a debug probe/programmer.

So it should be possible to do this by simply connecting the TX pin on the WCH-Link to the USART RX pin on the CH32X035 board and the RX pin on the WCH-Link to the USART TX pin on the CH32X035. Then select the serial port produced by the WCH-Link from Arduino IDE's Tools > Port menu.

I do have a CH32V003 board on hand, but haven't found the time to familiarize myself with it yet. And I don't have any experience with the CH32X035 either. So I don't know what needs to be done in terms of the Arduino sketch code in order to use the USART, but I have verified that the WCH-Link (I have the model marked "WCH-LinkE-RO-1v3") works just as I described as a USB to serial bridge adapter.

USART on the CH32X035 work with arduino core + WCH-Link out of the box - should be PA2 & PA3

Thanks for those last 2 answers. This is indeed what I have been trying, but it does not work. Maybe my board is faulty? Zwieblum, have you actually tried this for real, with this particular Weact board? The reason I ask is below:

I selected the CH32X035G8U board, as it is the only choice for a CH32X035 board, even though it is a different board to the Weact one.

On looking at the sources for the WCH32x035 core, the file for variant_CH32X035G8U.h says

#ifndef SERIAL_UART_INSTANCE
  #define SERIAL_UART_INSTANCE  1
#endif
// Default pin used for generic 'Serial' instance
// Mandatory for Firmata
#ifndef PIN_SERIAL_RX
  #define PIN_SERIAL_RX         PB11
#endif
#ifndef PIN_SERIAL_TX
  #define PIN_SERIAL_TX         PB10
#endif

However the Weact board has no physical pins for PB10 and PB11, so I tried using PA2 and PA3, with no success. File PeripheralPins.c indicates that PA2 and PA3 are connected to USART2 while PB10 and PB11 are connected to USART1.

So, I believe I need to tell my sketch to use USART2 instead of USART1 somehow. Does this need the creation of a whole new board variant? Or is there some way to do this from inside my sketch?

I see the lack of additional HardwareSerial objects even though the microcontroller has multiple UARTs has been reported to the developers here:

oops, what's described there is what I actually did to my ch core, too :slight_smile:

EDIT: no, that wasn't me. It's in the "main" branch, so you'll need to install it manually.

Not that I can see:

I see that a fix (using an alternative approach from what was shown in the reply on the issue) has been submitted:

@ralphrmartin you could try just defining the Serial2 object yourself in your sketch. Add this line to the top of the sketch:

HardwareSerial Serial2(USART2);

Then use the Serial2 object in the code. For example:

HardwareSerial Serial2(USART2);

void setup() {
  Serial2.begin(9600);
}

void loop() {
  Serial2.println("Hello, world!");
  delay(1000);
}

I tried this with the main branch from github (and with v 1.0.4), and then tried printing to Serial2, but I still get no output (with PA2 and PA3 connected to the Link-E RX and TX ports.

You are right. Looks like I patched a bit more :slight_smile:

Anyway, Best bet is to change variant_CH32X035G8U.h and set it to:

#ifndef SERIAL_UART_INSTANCE
  #define SERIAL_UART_INSTANCE  2
#endif
// Default pin used for generic 'Serial' instance
// Mandatory for Firmata
#ifndef PIN_SERIAL_RX
  #define PIN_SERIAL_RX         PA3
#endif
#ifndef PIN_SERIAL_TX
  #define PIN_SERIAL_TX         PA2
#endif

Hooray! That has got it working with Serial (not Serial2).

Thanks all for your help with this!

Summary for anyone who doesn't want to read the whole thread:

Download the latest CH32 core, unzip it and replace corresponding files in the arduino packages/WCH/hardware/ch32v/1.0.x/ folder with the unzipped ones..

Edit variants/CH32X035G8U/variant_CH32X035G8U.h to replace the code that looks similar to the below but refers to SERIAL_UART_INSTANCE 1 to say

#ifndef SERIAL_UART_INSTANCE
  #define SERIAL_UART_INSTANCE  2
#endif
// Default pin used for generic 'Serial' instance
// Mandatory for Firmata
#ifndef PIN_SERIAL_RX
  #define PIN_SERIAL_RX         PA3
#endif
#ifndef PIN_SERIAL_TX
  #define PIN_SERIAL_TX         PA2
#endif

[/quote]

Connect pins RA2 , RA3 to RX and TX of the WCHLink-E respectively.

Now you can use Serial as expected, with the serial monitor.

[Keep reading below - the latest core today also breaks USB_PD, unfortunately].

This solution has the unfortunate side effect of breaking the USB_PD example, which was working with an unchanged v 1.0.4 (apart from the serial output!), as now it gives compilation errors:

HardwareTimer.cpp:(.text.TIM3_IRQHandler+0x0): multiple definition of TIM3_IRQHandler'`

The fix suggested at
https://github.com/openwch/arduino_core_ch32/issues/77
does not resolve the compilation error, and also breaks the blinky example.

Not on my system.

Could you please provide the complete error message? There sould be a line telling you where TIM3_IRQHandler was defined the first time.

/Users/ralph/Library/Arduino15/packages/WCH/tools/riscv-none-embed-gcc/8.2.0/bin/../lib/gcc/riscv-none-embed/8.2.0/../../../../riscv-none-embed/bin/ld: /Users/ralph/Library/Caches/arduino/cores/4bc2b5ff1fea33627510baec3699fa75/core.a(HardwareTimer.cpp.o): in function TIM3_IRQHandler': HardwareTimer.cpp:(.text.TIM3_IRQHandler+0x0): multiple definition of TIM3_IRQHandler'; /Users/ralph/Library/Caches/arduino/sketches/F458F1554934B9A4D499223271D0F159/libraries/USBPD_SINK/usbpd_sink.c.o:usbpd_sink.c:(.text.TIM3_IRQHandler+0x0): first defined here
collect2: error: ld returned 1 exit status

exit status 1

Compilation error: exit status 1