DSO183

DOS183 controlado por PC (CH32V003)

Posted by jm on Wednesday, August 26, 2026

Controlando el osciloscopio DSO183 de JYETech mediante PC usando el CH32V003

Hace ya un tiempo he usado el frontend analógico que proporciona el pequeño osciloscopio DSO183 de JYETech para Techo. La pega es que el control del acoplamiento y la sensibilidad son manuales (mediante los switchs deslizables), así que había que probar a controlar esto también desde el PC. La verdad que ha ido bien, pero tiene ciertas limitaciones.

Limitaciones hardware

Como he usado un relé, G6K-2F, solo tengo dos estados y los switchs deslizables tienen tres:

  • Acoplamiento
    • DC
    • AC
    • GND
  • SEN1
    • 10mV
    • 0.1V
    • 1V
  • SEN2
    • x1
    • x2
    • x5

A mi no me hace falta tanto control puesto que el software que he desarrollado se vale de zoom digital (y funciona muy bien), así que para simplificar el circuito simplemente he optado por las siguientes opciones:

  • Acoplamiento
    • DC
    • AC
  • SEN1
    • 10mV
    • 1V
  • SEN2
    • x1
    • x5

Esto tiene un problema : el osciloscopio físico tiene un offset en los operacionales y con estas configuraciones no se puede eliminar. A mi me es igual, porque todo el tratamiento es mediante software y esto tiene fácil solución. Esta también es una de las razones por las que desde el principio decidí que el hardware solo proporcionaría datos hardware… todo el tratamiento se haría mediante software por su enorme flexibilidad (aunque a veces tu jefe te pida que la llave inglesa que te pidió también envíe naves al espacio…).

Evidentemente puedes solucionar esto usando más relés… pero no sé si en realidad merece la pena. En mi caso no.

Botones

Al final también me puse a controlar los botones aunque no me hacen falta:

  • OK
  • +
  • -
  • SEL

Yo también añadiría el botón de reset, y es posible que lo haga…

Esquema

Relés

Como estoy usando el CH32V003 alimentado a 3.3V el G6K-2F es también de 3V. También fíjate que están los diodos de protección.

                            CPL
          ┌──────────────────|<|──────────────┐
          │                                   │
          │               + BOBINA -          │
 PC0      ├───────o 1──────[     ]──────o  8──┤  GND
          │                                   │
          │                                   │
 DC1 [1]──┼───────o 2                 7 o─────┼──[5] DC2
          │        \                     /    │
          │         \                   /     │
     [2]──┼──────────o 3             6 o──────┼──[6]
          │                                   │
 AC1 [3]──┼───────o 4                 5 o─────┼──[7] AC2
          │                                   │
          └────────────── G6K-2F ─────────────┘
                               SEN1
             ┌──────────────────|<|──────────────┐
             │                                   │
             │               + BOBINA -          │
 PC1         ├───────o 1──────[     ]──────o  8──┤  GND
             │                                   │
             │                                   │
 10mV_1 [1]──┼───────o 2                 7 o─────┼──[5] 10mV_2
             │        \                     /    │
             │         \                   /     │
        [2]──┼──────────o 3             6 o──────┼──[6]
             │                                   │
   1V_1 [3]──┼───────o 4                 5 o─────┼──[7] 1V_2
             │                                   │
             └────────────── G6K-2F ─────────────┘
                               SEN2
             ┌──────────────────|<|──────────────┐
             │                                   │
             │               + BOBINA -          │
 PC2         ├───────o 1──────[     ]──────o  8──┤  GND
             │                                   │
             │                                   │
   x1_1 [1]──┼───────o 2                 7 o─────┼──[5] x2_2
             │        \                     /    │
             │         \                   /     │
        [2]──┼──────────o 3             6 o──────┼──[6]
             │                                   │
   x5_1 [3]──┼───────o 4                 5 o─────┼──[7] x5_2
             │                                   │
             └────────────── G6K-2F ─────────────┘

Botones

Yo he utilizado un SS8050 porque tenía a mano suficientes, así que te tocará calcular a ti la Rb para que el transistor entre en las regiones de corte y saturación.

Todos los botones se controlan de la misma forma, así que simplemente pongo el dibujo de uno, con sus cuatro pads. Fíjate bien en la orientación de los transistores.

Para el control usamos las patillas PC3-6.

                           0 V
                           o                           o
                           |
                           |
                           E
                           ^
                          /
Control o───[ 3.3 kΩ ]───B  NPN       BUTTON
                          \
                          C
                          |
                          |
                          o                           o
                        +3.3 V

Ajustes

Lo que sí tendrás que hacer tras tener todo el montaje es ajustar C5 (C4 creo que no lo he llegado a tocar para nada) usando una onda cuadrada para contrarestar las capacidades parásitas y tener el máximo BW.

Código

En realidad este proyecto está en pañales y no debería mostrar el código, pero para que os hagáis una idea, estoy utilizando el esquema habitual de siempre:

main.c

#include "debug.h"

#include "dso183_driver.h"
#include "parser.h"
#include "usart.h"

/*********************************************************************
 * @fn      main
 *
 * @brief   Main program.
 *
 * @return  none
 */
int main(void)
{
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  SystemCoreClockUpdate();
  Delay_Init();

  USARTx_CFG();
  dso183_driver_init();
  parser_init();

  while(1)
  {
    // Parseado de los comandos
    if (parser_command_ready())
    {
      char cmd = parser_get_command();
      int opt = parser_get_int_from_command();

      switch (cmd) {
        case 'b':
          dso183_driver_buttons(opt);
          break;
        case 'c':
          dso183_driver_coupling(opt);
          break;
        case 's':
          dso183_driver_sen1(opt);
          break;
        case 'x':
          dso183_driver_sen2(opt);
          break;
      }
      parser_reset();
    }
  }
}

driver.c

#include "dso183_driver.h"

#include <ch32v00x.h>

enum {dc, ac};
enum {mV, V};
enum {x1, x5};
enum {btnOk, btnM, btnm, btnSel, btnSelAju};

// --------------------------------------------------------
void dso183_driver_buttons(uint8_t opt)
{
  switch (opt)
  {
    case btnOk:
      GPIO_WriteBit(GPIOC, GPIO_Pin_3, Bit_SET);
      Delay_Ms(250);
      GPIO_WriteBit(GPIOC, GPIO_Pin_3, Bit_RESET);
      break;
    case btnM:
      GPIO_WriteBit(GPIOC, GPIO_Pin_4, Bit_SET);
      Delay_Ms(250);
      GPIO_WriteBit(GPIOC, GPIO_Pin_4, Bit_RESET);
      break;
    case btnm:
      GPIO_WriteBit(GPIOC, GPIO_Pin_5, Bit_SET);
      Delay_Ms(250);
      GPIO_WriteBit(GPIOC, GPIO_Pin_5, Bit_RESET);
      break;
    case btnSel:
      GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_SET);
      Delay_Ms(250);
      GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_RESET);
      break;
    //
    case btnSelAju:
      GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_SET);
      Delay_Ms(4000);
      GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_RESET);
      break;
    //
  }
}

// --------------------------------------------------------
void dso183_driver_coupling(uint8_t opt)
{
  switch (opt)
  {
    case dc:
      GPIO_WriteBit(GPIOC, GPIO_Pin_0, Bit_RESET);
      break;
    case ac:
      GPIO_WriteBit(GPIOC, GPIO_Pin_0, Bit_SET);
      break;
  }
}
...
// --------------------------------------------------------
void dso183_driver_init()
{
  GPIO_InitTypeDef GPIO_InitStructure = {0};

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_30MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  Delay_Ms(10);
  GPIO_WriteBit(GPIOC, GPIO_Pin_All, Bit_RESET);
}

Demostración

Aquí tienes un vídeo demostración para ver su funcionamiento.

DSO183 controlado por PC