1Hz to 150KHz PWM Frequency Generator Module (HCMODU0134)

Modules for measurement or testing of signals
Post Reply
Site Admin
Posts: 870
Joined: Sun Aug 05, 2012 4:02 pm

1Hz to 150KHz PWM Frequency Generator Module (HCMODU0134)

Post by admin » Fri Apr 12, 2019 12:42 pm


A signal generator module which is capable of generating a single PWM output with a programmable frequency between 1Hz to 150KHz and a duty cycle between 1 to 100 %. Both frequency and duty cycle can be programmed via 4 push buttons which increment or decrement the frequency in 1Hz, 10Hz, 100Hz, or 1KHz steps (depending of frequency) and duty cycle in 1% increments (see specification below). Current frequency and duty cycle can be viewed on a clear 1.5" display consisting of white text against a blue backlight.


Product Code: HCMODU0134
Supply Voltage: 3.3 to 16V
Supply Current: ~30mA (no load)
PWM Amplitude: PWM amplitude = Supply voltage
PWM Freq (min): 1Hz
PWM Freq (max): 150KHz
PWM Freq Resolution: 1Hz (<100Hz), 10Hz (<1KHz), 100Hz (<10KHz), 1KHz (<150KHz)
PWM Duty resolution: 1% (>2% at 100KHz and above)
PWM Output current: 30mA at 16V Vin (output is supplied via 100R pullup resistor from Vin)


Frequency display:

1 = 1Hz
100 = 100Hz
1.00 = 1KHz
10.0 = 10KHz
1.0.0 = 100KHz


I noticed there are two PWM outputs, does this mean the module can generate two independent PWM signals?

No, the two PWM output terminals are shorted together and therefore are the same signal.

On the underside I see a serial interface, what is this for?

This serial interface allows for the frequency and duty cycle to be remotely programmed via a serial interface. However in our test we have had mixed success in getting this interface to work reliably. Therefore we do not advertise or guarantee this feature. If you wish to experiment with this interface the serial interface settings are 9600 Baud, 1 stop bit, and no parity. To change the frequency send the following command:

F101: set frequency to 101HZ (001 to 999)
F1.05: set frequency to 1.05KHZ (1.00 to 9.99)
F10.5: set frequency to 10.5KHZ (10.0 to 99.9)
F1.0.5: set frequency to 105KHZ (1.0.0 to 1.5.0)

To set the duty cycle:

DXXX: set PWM duty cycle to XXX: (001 to 100)
Such as D050, set PWM duty cycle is 50%

Libraries, example code, and diagrams are provided as an additional free service by Hobby Components and are not sold as part of this product. We do no provide any guarantees or warranties as to their accuracy or fitness for purpose.

Descriptions and diagrams on this page are copyright Hobby Components Ltd and may not be reproduced without permission.

Posts: 3
Joined: Wed Aug 27, 2014 2:03 pm
Location: Gateshead, England

Re: 1Hz to 150KHz PWM Frequency Generator Module (HCMODU0134)

Post by BreadBoard » Fri Nov 17, 2023 12:23 am

There are multiple versions of hardware and firmware for these modules. After digging around the internet for a few days it appears that there are at least 3 different microcontroller chipsets used in these modules:
  1. STM8S003F3 SOIC-20
  2. N76E003 SOIC-20
  3. Unmarked SOIC-16
These boards also have different production marks on the PCB e.g.
  • LPWM - as shown in the picture above
  • HW-753
  • HW-753 V3.0 - The version shipped to me by Hobby Components in Nov 2023
I have seen reports of different versions returning different responses to commands and even some boards that could not be made to communicate over the serial port. It would appear that the buyer is at the mercy of whatever hardware and firmware that is supplied. I can find no documented source to determine what firmware version is installed.

The major issue with attempting to communicate with devices like these over usb is the delay introduced by the usb stack and the internal buffers on the usb-serial adaptor. The microcontroller needs to interpret the message and send the response to the usb adaptor. The adaptor stores this response in it's internal buffer and waits until either the buffer is full or some device specific timeout occurs before transmitting the data over usb. The OS usb stack also introduces further delays due to the use of internal buffers for both usb messages and serial rx/tx buffers. So there can be quite a delay between the microcontroller sending data out from it's uart until it becomes available to the user program.

The following is a crude command line program, written in C#, for setting the frequency and pulse width duration.
  1. /* File: setpwm.cs
  2.  * Date: 16 Nov 2023
  3.  *
  4.  * This program demonstrates serial access to the XY-LPWM Module
  5.  * using C#.
  6.  *
  7.  * This code was written and tested against the following hardware:
  8.  *
  9.  * HCMODU0134 1Hz to 150KHz PWM Frequency Generator Module (HW-753 V3.0)
  10.  * FT232RL USB-Serial TTL 3V3 Adaptor Module
  11.  * Medion Erazer Laptop
  12.  * Windows 10 Home
  13.  *
  14.  * Usage:
  15.  *
  16.  *    setpwm COMx Fxxx Dxxx
  17.  *
  18.  *    Use 'Fxxx', 'Fx.xx', 'Fxx.x' or 'Fx.x.x' to set frequency
  19.  *    Use 'Dxxx' to set duty cycle
  20.  *
  21.  * Example:
  22.  *
  23.  *    setpwm F3.14 D059
  24.  *
  25.  * Example Response:
  26.  *
  27.  *    F3.14 OK
  28.  *    D059 OK
  29.  *    F=3.14KHz   D= 59%
  30.  *
  31.  * Disclaimer:
  32.  *
  33.  * This code is for demonstration purposes only and is not intended
  34.  * as an example of production quality code.
  35.  */
  36. using System;
  37. using System.IO;
  38. using System.IO.Ports;
  39. using System.Threading;
  41. class SetPWM
  42. {
  43.     static void Main(string[] args)
  44.     {
  45.         if (args.Length == 3) {
  46.             SerialPort mySerialPort = new SerialPort(args[0], 9600, Parity.None, 8, StopBits.One);
  48.             try {
  49.                 mySerialPort.Open();
  51.                 // send the first parameter
  52.                 mySerialPort.Write(args[1]);
  53.                 // wait for device to respond & usb buffers to flush
  54.                 Thread.Sleep(1000);
  55.                 // read the response
  56.                 string response = mySerialPort.ReadExisting();
  58.                 // check the response 'DOWN' is OK anything else is a problem
  59.                 if (response.Contains("DOWN")) {
  60.                   Console.WriteLine("{0} OK", args[1]);
  61.                 } else {
  62.                   Console.WriteLine("Bad Command {0}", args[1]);
  63.                 }
  65.                 // send the second parameter
  66.                 mySerialPort.Write(args[2]);
  67.                 // wait for device to respond & usb buffers to flush
  68.                 Thread.Sleep(1000);
  69.                 // read the response
  70.                 response = mySerialPort.ReadExisting();
  72.                 // check the response 'DOWN' is OK anything else is a problem
  73.                 if (response.Contains("DOWN")) {
  74.                   Console.WriteLine("{0} OK", args[2]);
  75.                 } else {
  76.                   Console.WriteLine("Bad Command {0}", args[2]);
  77.                 }
  79.                 // get the device status
  80.                 mySerialPort.Write("read");
  81.                 // wait for device to respond & usb buffers to flush
  82.                 // longer delay due to longer message
  83.                 Thread.Sleep(1500);
  84.                 // display the device status, varies by model/firmware
  85.                 Console.Write(mySerialPort.ReadExisting());
  87.                 mySerialPort.Close();
  88.             } catch (Exception ex) {
  89.                 Console.WriteLine("Error: {0}", ex.Message);
  90.             }
  91.         } else {
  92.             // display usage if wrong number of arguments supplied
  93.             Console.WriteLine("Invalid number of arguments");
  94.             Console.WriteLine();
  95.             Console.WriteLine("Usage:");
  96.             Console.WriteLine("    setpwm COMx Fxxx Dxxx");
  97.             Console.WriteLine();
  98.             Console.WriteLine("Use 'Fxxx', 'Fx.xx', 'Fxx.x' or 'Fx.x.x' to set frequency");
  99.             Console.WriteLine("Use 'Dxxx' to set duty cycle");
  100.             Console.WriteLine();
  101.             Console.WriteLine("Example:");
  102.             Console.WriteLine("    setpwm F3.14 D059");
  103.         }
  104.     }
  105. }
  107. /*
  108.  * The author of this work hereby waives all claim of copyright (economic
  109.  * and moral) in this work and immediately places it in the public domain;
  110.  * it may be used, distorted or destroyed in any manner whatsoever without
  111.  * further attribution or notice to the creator.
  112.  */
You do not require Visual Studio or any other IDE to compile this code. All versions of Microsoft Windows that I have used with the .Net framework installed have also contained a minimal C# compiler. This compiler can be found in the .Net Framework folder, for example:




where vx.xxxx is the version of .Net you have installed eg. v3.5, v4.0.30391 etc.

To compile the program from the command line simply open a command prompt and cd to the location of the source file then invoke the compiler using:

C:\Windows\Microsoft.NET\Framework64\v3.5\csc.exe setpwm.cs

This will produce the executable file

To use the program from the command line type:

setpwm COMx Fxxxx Dxxx

COMx is the COM port the device is on e.g. COM6
Fxxxx is the frequency desired.
Use Fxxx for Hz e.g. F123 for 123Hz
Use Fx.xx for 1KHz to 9KHz e.g. F3.14 for 3.14KHz
Use Fxx.x for 10KHz to 99KHz e.g. F36.5 for 36.5KHz
Use Fx.x.x for 100KHz to 150KHz e.g. F1.2.3 for 123KHz
Dxxx is the duty cycle percentage, must be a 3 digit integer with leading zeros e.g. 050 is 50%. 000 and 100 are legal values.

The D and F arguments must be upper case.

I can only state that this code works reliably on my system with my hardware, your mileage may vary, but I hope this code is a useful starting point for someone.

Post Reply

Return to “Measurement / Signal Generation”