Controlamos el generador o la lucha contra el ADC en el STM32F030

Históricamente, de alguna manera no funcionó para mí con la familia STM32F030, hace unos 5 años intenté trabajar con ellos y durante mucho tiempo me sorprendió el trabajo torpe de la mayoría de los periféricos, y luego los califiqué. Y el otro día aún tenía que volver a esta serie, era necesario medir por un mínimo dinero el voltaje constante en una batería de plomo (o ensamblaje de hasta 4 piezas en serie) de 8 a 60V con una precisión no peor que ± 0.1V con una baja frecuencia de sondeo.

La solución del problema "de frente" hizo posible medir con precisión el voltaje solo cuando el valor de la entrada ADC es más de 1.5 ... 1.6V, es decir, solo en la segunda mitad del rango, lo que significaba 30 ... 60V para mí en lugar de los 8 necesarios. .60V. El problema principal estaba en el rango de 0 ... 1.6V, todo parecía que mi divisor de voltaje estaba "flotando" o el voltaje de referencia para el ADC (V ref ) era extremadamente inestable.

Era necesario resolver rápidamente el problema, aunque no de la manera más elegante, pero al menos sin muletas obvias. Para hacer esto, primero fue necesario estudiar el problema y entender de dónde crecen las “piernas”, y luego eliminar este problema. Si no funciona, al menos evítelo para obtener un dispositivo que funcione y enviárselo al cliente.



Esencia de la tarea.


En general, he estado tratando de no abordar ese problema durante mucho tiempo, pero luego un pariente se me acercó y, a tiempo parcial, una buena persona que también trabaja en temas cercanos a mí: recolecta pequeños SES en algún lugar de la región de Moscú. No quería negarme, e incluso en ese momento esta tarea me pareció "un par de horas de hierro + un par de horas de código". El proyecto en Altium Designer realmente me llevó un par de horas, pero la lucha contra el ADC se consumió toda la noche, así que decidí compartir información para que otros no perdieran el tiempo.

El dispositivo en sí es extremadamente simple, el algoritmo es el siguiente:

  • mida el voltaje en el conjunto de 1 ... 4 baterías de plomo conectadas en serie;
  • si el voltaje es menor que el "umbral inferior", cierre el relé y se encenderá el generador, que carga nuestras baterías;
  • si el voltaje sube por encima del "umbral inferior + histéresis", es decir, las baterías se cargan al umbral establecido, luego apague el generador;
  • Si el voltaje está por encima del "umbral superior", entonces prohibimos encender el generador por si acaso.

Eso es todo! Ejemplo: hay una batería de 12V y el inversor se alimenta de ella. Si el voltaje cae por debajo del "umbral inferior", el valor predeterminado es 10.2V, luego encienda el generador. Si el voltaje de la batería ha aumentado a "umbral más bajo + histéresis", apáguelo. Por defecto, la histéresis está configurada en 2V y es necesaria para que el generador de gasolina no se apague tan pronto como cargue ligeramente la batería a 10.3V. De encendido / apagado constante, el generador simplemente morirá. Bueno, por si acaso, protección: si el voltaje de la batería es superior a 14,4 V, no encienda el generador exactamente.

El algoritmo es simple y directo, además, fue necesario hacer un pequeño menú para poder cambiar tres variables: "umbral inferior", "histéresis", "umbral superior". Nada complicado, pero el diablo está en los detalles.

Inicialmente, la compañía donde trabaja el pariente utilizó un dispositivo chino con una funcionalidad similar. De los inconvenientes menores: era imposible cambiar la histéresis, ya que la potencia necesitaba una fuente adicional de 5V y una medición de solo 30V, es decir, para 1 o 2 baterías. De los grandes inconvenientes: el dispositivo chino a veces se congela y se reinicia en el momento del arranque del generador de gasolina que controlaba. La última "característica" se convirtió en la razón del intento de abandonar la decisión china.

Querían eliminar de mí todas estas desventajas y que el precio del dispositivo era como el de los chinos, es decir, $ 10. La "bagatela diabólica" en este caso fue que querían comprarme un dispositivo terminado por $ 10 en lotes de solo 20-30 piezas, aunque era estable y con frecuencia suficiente. Es decir, tuve que hacer que el dispositivo fuera mucho mejor y mucho más barato que los chinos en una serie pequeña, también necesito ganar dinero en el futuro. Sí, también fui divertido en los primeros 10 minutos, pero cuando me di cuenta de esta situación, ya dije "SÍ", es decir, no había tierra más allá del Volga para mí ...

Resolviendo problemas de hierro


Como escribí anteriormente, el problema principal es la operación inestable del dispositivo durante el inicio del generador. Como resultado, se compró un dispositivo chino con aliexpress para pruebas e investigación. La razón principal de la "demolición de la cabeza" resultó no estar en el generador, sino en el relé :)) Al momento de cambiar la fuente de alimentación, un pulso con una amplitud de aproximadamente 25V pasó a través del bus de 3.3V, lo que daría una pista ... Lo mismo ocurrió con los circuitos de señal. En el circuito chino, para combatir este problema, se colocaron diodos LL4148, que bloquearon el camino de la interferencia. Esto resultó ser suficiente para que el dispositivo funcione normalmente en la mesa, pero no en un montón de interferencia adicional externa, como un generador y otro equipo. Para deshacerme permanentemente de lo descrito anteriormente, decidí usar el aislamiento galvánico a través de un "optoacoplador + dc / dc", que eliminó por completo el contacto eléctrico y la ruta de interferencia entre la bobina del relé de control y el resto del circuito.



Una alternativa a esta solución fue el uso de diodos protectores de TVS junto con un estrangulador de modo común, así como la complicación del filtro de la fuente de alimentación. ¿Pero por qué una granja tan colectiva? Poner dc / dc es más fácil, pero en la práctica resultó aún más barato: el módulo chino Mornsun B0505S-1WR2 me costó $ 0.4 con el costo de un estrangulador de modo común por un pequeño lote de aproximadamente $ 0.32.

Como resultado, después de tal decisión y pruebas de prototipo, el dispositivo comenzó a funcionar como un rifle de asalto Kalashnikov y los problemas con el reinicio desaparecieron. En general, estoy un poco sorprendido de que el relé + un poco el generador aún se haya visto obligado a reiniciar el stm-ku, los desarrolladores chinos, en principio, hicieron todo bien: 10 kOhm + 0.1 uF para reiniciar, bloqueando los condensadores para la alimentación, cuentas de ferrita, todo fue igual, pero resultó ser igual de todos modos no es suficiente

La segunda desventaja de los "chinos" fue la necesidad de energía adicional, aparentemente guardada en CC / CC. Resolví el problema en la frente: tomé energía de la señal de entrada, directamente de un conector. Para hacer esto, solo tenía que poner dc / dc, que digeriría al menos 4 * 14.4V, es decir, 57.6V. Mi elección recayó en el LMR16010PDDAR. En primer lugar, esto es Texas y eso es todo. En segundo lugar, los camaradas asiáticos me sugirieron que llevara este chip muy barato.

El párrafo anterior decidió exhaustivamente el tercer inconveniente: la capacidad de conectar hasta 4 baterías en serie. DC / DC digiere fácilmente 60V, comienza a tratar de quemarse solo a 72 ... 73V, por lo que el máximo de 57.6V definitivamente no le da miedo. Al divisor de voltaje en general no le importa cuánto hay en la entrada, por lo que todo se decidió con un mínimo esfuerzo.

Puede ver cómo se implementa todo esto en el diagrama aquí: PDF . El esquema es lo suficientemente grande, por lo que no lo llené con una imagen. Por cierto, en pdf también puede ver las dimensiones con una placa de circuito impreso, pero no hay nada sobrenatural.

Como resultado, se ordenaron componentes para 10 dispositivos para el primer lote de prueba, y después del ensamblaje resultó así:



No fue sin incidentes: cuando creé el componente para el módulo dc / dc mezclé las patas 1 y 2 en algunos lugares, tuve que tomar una pequeña granja. Aunque lo hice con más cuidado en los tableros posteriores para que nadie se diera cuenta, el tablero en la foto permaneció conmigo como una herramienta de depuración por si acaso o para mejoras de software si el cliente se le ocurrió algo durante las pruebas.

Lucha contra la precisión del ADC


Ahora pasemos a la parte principal del artículo. Como escribí al principio del artículo, el ADC F030 resultó ser inexacto, es decir, hasta un voltaje de 30 ... 32V en la entrada del dispositivo, las lecturas flotaron con una desviación de hasta 15 ... 20%, y luego el error desapareció gradualmente. Una cosa me gustó: a primera vista, las desviaciones tenían cierta regularidad, lo que significa que esto no es un error aleatorio y puede rastrearlo e intentar corregirlo.

Tomemos un poco más de detalles sobre el error ... Después de la conversión, el ADC envía los datos sin procesar al registro DR , que contiene un valor de 0 a 4095 (2 12 ). Para convertir este valor a voltaje, debe multiplicarlo por el paso de cuantización. En mi caso, el voltaje en el pin VDDA, del cual el ADC toma el soporte, fue 3.3072V y, en consecuencia, el paso es 3.3072V / 4096 = 0.000807V, lo redondeé a 0.0008. Para obtener el voltaje en la entrada del dispositivo, el voltaje obtenido debe multiplicarse por el coeficiente del divisor de voltaje, en mi caso la resistencia en el brazo superior es de 100 kOhm, y en el brazo inferior de 4.7 kOhm, lo que da al divisor 22.2765. En base a esto, el voltaje en la entrada del dispositivo, es decir, el voltaje de la batería, se encuentra usando la fórmula:

float voltageReference = 0.0008; float voltageDivider = 22.2765; adcVoltageResult = (float)adcData * voltageReference * voltageDivider; 

Resulta que después de leer los datos ADC1-> DR , se convierten al tipo flotante y simplemente se multiplican por los coeficientes, que son constantes, y obtenemos el resultado en los voltios habituales. En la práctica, resultó que todo es muy malo con precisión.

Recordando la navaja de Hanlon, comencé a buscar el lugar donde había cometido un error. Primero revisé el voltaje en el tramo del VDDA, pensé que de alguna manera flota y depende del voltaje de entrada, por ejemplo, el LDO está defectuoso. Armado con un multímetro de escritorio, monitoreó el voltaje en el VDDA y cambió el voltaje de entrada de 8 a 60V, mientras que el voltaje en la pata del VDDA permaneció muerto a 3.3072V, solo flotaron los siguientes 2 signos, lo cual es muy bueno para un medidor lineal de 10 centavos.

El siguiente lugar para posibles errores fue el divisor de voltaje. Aunque me pareció extraño que las resistencias de Bourns sean ± 0.1% flotantes, por lo que los datos tienen un error de hasta 20% y este error no es lineal. Llevé a cabo el mismo experimento: medí el voltaje después del divisor con un multímetro, y cambié el voltaje de entrada en pasos de 0.5V, y como resultado, el coeficiente del divisor también se fijó firmemente en 22.2768.

En ese momento, comenzó a volverse interesante. Solo podía dudar de un componente: el amplificador operacional LMV611MFX. Este amplificador operacional se incluye como un seguidor de voltaje. El voltaje ANTES y DESPUÉS fue el mismo hasta 4 decimales. Extraño ... Por la hoja de datos no está mal y es el mismo TI, lo dudaba, pero decidí comprobarlo, porque Es esta opamp nunca utilizada. Por si acaso, mi favorito y probado en un montón de proyectos OPA320, que tengo en las bobinas, soldado en su lugar y mostró el mismo resultado.

El último componente permaneció: MK, es decir, su ADC. A lo largo de los años de uso de STM, estoy acostumbrado a confiar en sus productos, especialmente porque solo tomo los originales, así que pensé por último en MK. Lo primero que pensé fue que olvidé calibrar o lo hice mal. Útil en el manual de referencia, exigieron no solo reducir el ADC escribiendo cero en el bit ADEN , sino también establecer 1 en el bit ADDIS y 0 en el bit DMAEN . Los últimos 2 pasos no se han tomado, por lo general, corté el ADC y todo funciona bien, como resultado, corregí un fragmento de código con calibración:

  /* disable ADC */ if (ADC1->CR & ADC_CR_ADEN) { ADC1->CR |= ADC_CR_ADDIS; while (ADC1->CR & ADC_CR_ADEN) {} } /* calibrate ADC */ ADC1->CR |= ADC_CR_ADCAL; while(ADC1->CR & ADC_CR_ADCAL) {} /* reset configuration */ ADC1->CFGR2 = 0; /* enable device */ ADC1->CR = ADC_CR_ADEN; while(!(ADC1->ISR & ADC_ISR_ADRDY)); 

Desafortunadamente, no ayudó y decidí llevar a cabo el siguiente experimento ... Ya verifiqué los coeficientes y son 100% correctos, por lo que aplicaré el voltaje de la fuente de alimentación del laboratorio a la entrada, lo cambiaré y mostraré los resultados brutos de la medición de ADC en un indicador de siete segmentos, y luego lo compararé con lo que debería estar allí con lo que realmente mediste. Como resultado, recibí los siguientes resultados:



Como puede ver, el gráfico teórico tiene una excelente linealidad, porque No unido al hierro. El gráfico basado en datos reales también es casi lineal con desviaciones mínimas. De hecho, el gráfico con datos reales se puede combinar con el gráfico teórico mediante transferencia paralela a una cierta constante. Hablando en el lenguaje de la electrónica, el ADC tiene un desplazamiento!

De acuerdo con los datos sobre los que se construyeron los gráficos, descubrí que el ADC tiene un desplazamiento en diferentes puntos de 71 ... 73 pasos. Ese era el problema, y ​​pensé "no linealidad" porque el cambio de 71 pasos a 10 V es de aproximadamente el 14%, y a 30 V ya es del 4%. Es decir, si construye un gráfico de desviaciones en%, entonces la dependencia tendrá una forma exponencial, pero dicho gráfico no es interesante.

Se decidió que para aclarar los resultados, intente introducir otra variable en la fórmula, que cambiará mis valores y tendrá la siguiente forma:

 uint16_t offsetVoltage = 72; float voltageReference = 0.0008; float voltageDivider = 22.2765; adcVoltageResult = ((float)(adcData+offsetVoltage))*voltageReference*voltageDivider; 

Después de estas simples manipulaciones, mi dispositivo comenzó a medir con precisión el voltaje y los datos dejaron de flotar. Hasta ese momento, se encontraba a 72 * 0.0008V * 22.2768 = 1.28V , lo cual es muy crítico en el caso del control de una batería. La batería de plomo ciertamente no explota como el ion de litio, pero aún así se bloquea rápidamente, especialmente si se descarga constantemente no a 10.2V, sino a 8.92V.

Aquí hay una pequeña historia sobre una pequeña pieza de hierro. Espero que alguien encuentre este material útil o al menos simplemente interesante de leer. Tenga cuidado con todos estos ADC y otras cosas desagradables :))

UPD olartamonov muy celosamente pide no engañar a las personas y usar el código de calibración del manual de referencia: realizó el cambio con mucho gusto. Desafortunadamente, en mi caso, esto no cambió la situación y el cambio no fue a ninguna parte. Probablemente el problema esté en el chip en sí. según lo indicado por el Departamento de Estado lanzó productos falsificados

Competencia


Se está llevando a cabo una competencia entre proyectos técnicos entre los compañeros de PCBway , cualquiera puede participar. Las reglas son simples. Las placas de circuito impreso para su proyecto lo harán de forma gratuita. ¡Y lo más importante, premios! Estos son algunos documentos verdes con caballeros estadounidenses en su PayPal + moneda virtual para los que puede solicitar placas de circuito impreso + honor y respeto + la oportunidad de obtener una oferta de trabajo en algún lugar fuera del CIS :)) Recomiendo especialmente a los estudiantes que participen, el nivel técnico no es demasiado alto allí , aunque a partir de la experiencia de concursos anteriores hay proyectos muy sólidos, por lo que una caja de bricolaje "fuerte" puede llegar fácilmente a los ganadores.

Source: https://habr.com/ru/post/448202/


All Articles