consulta, porque no tengo salida , o estoy haciendo algo mal, uso el arduino uno para lograr un pwm mayor que con analogwrite, tambien esta el manejo del encoder, que funciona probé con attachInterrupt y funciono todo bien , algún registro esta mal
volatile int value;
volatile int lastEncoded = 0;
int A = 2; //variable A a pin digital 2 (DT en modulo)
int B = 4; //variable B a pin digital 4 (CLK en modulo)
void setup()
{
pinMode(9,OUTPUT);
pinMode(A, INPUT); // A como entrada
pinMode(B, INPUT); // B como entrada
digitalWrite(A, HIGH);
digitalWrite(B, HIGH);
OCR1A=value;
PCICR |= B00000100; // Activamos las interrupciones del puerto PD
PCMSK2 |= B00010100;
sei();
TCNT1 = 0;
TCCR1A = _BV(COM1B1) | _BV(WGM11);
TCCR1B = _BV(CS10) | _BV(WGM12);
}
void loop()
{
duty();
}
ISR (PCINT2_vect) {
int MSB = digitalRead(A);
int LSB = digitalRead(B);
int encoded = (MSB << 1) |LSB;
int sum = (lastEncoded << 2) | encoded;
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011)
value++;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000)
value--;
lastEncoded = encoded;
if (value <= 0)
value = 0;
if (value >= 255)
value = 255;
}
void duty() {
OCR1A = 255 - value;
}
después de estar 4 horas leyendo , así me funciono, todavía no comprendo bien como configurar los timer, pero asi me regula , no se si la frecuencia es correcta ya que uso la placa arduino uno el reloj es de 16.000 y ahora esta calculado en 8.000.000, necesito un tutorial para torpes.....
volatile int value;
volatile int lastEncoded = 0;
int A = 2; //variable A a pin digital 2 (DT en modulo)
int B = 4; //variable B a pin digital 4 (CLK en modulo)
void setup()
{
pinMode(9,OUTPUT);
pinMode(A, INPUT); // A como entrada
pinMode(B, INPUT); // B como entrada
digitalWrite(A, HIGH);
digitalWrite(B, HIGH);
//Endable Interrupts for PCIE2 arduino Pins (D0-7)
PCICR |= (1<<PCIE2);
//Setup pins 2,4
PCMSK2 |= (1<<PCINT18);
PCMSK2 |= (1<<PCINT20);
TCCR1A = _BV(COM1A1) | _BV(WGM11);
TCCR1B = _BV(CS10) | _BV(WGM12) | _BV(WGM13) ;
ICR1 = 73; // frequency = 8000000/73 = 109.589 kHz
// OCR1A = 0; //0% Duty Cycle or Full Off.
sei();
}
void loop()
{
duty();
}
ISR (PCINT2_vect) {
int MSB = digitalRead(A);
int LSB = digitalRead(B);
int encoded = (MSB << 1) |LSB;
int sum = (lastEncoded << 2) | encoded;
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011)
value++;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000)
value--;
lastEncoded = encoded;
if (value <= 0)
value = 0;
if (value >= 255)
value = 255;
}
void duty() {
OCR1A = 255 - value;
}
Eso no es PWM mayor y de hecho PWM va de 0 a 100 jamás puede ser mayor.
Por otro lado, tiene lógica tu comentario @anon90500195 pero como cuesta expresarse debidamente!! @callecuatro1976 perdona que sea quisquilloso pero llevas muchos hilos y es importante explicar debidamente lo que se pretende, de lo contrario ocurre que por algo nadie te responde.
Ojo que puedo estar equivocado pero como justamente lo único que podría ser distinto al resultado de analogWrite() es la frecuencia, deduje que se refiere a eso.
hola, ya casi esta terminado el proyecto, ahora tengo una duda y no se como resolverla, me gustaría mostrar el voltaje en un oled, eso lo logro con el adc, bien me gustaría hacerlo sin el adc, ósea tengo la variable value que mueve el pwm, va de 0 a 255, como haría el calculo para que una variable x sea 18.0 en la pantalla oled cuando value es 255 subo el codigo para que se vea y se entienda mejor.
#include "avr/interrupt.h";
#include <EEPROM.h>
#include <stdio.h>
#include <Wire.h> // libreria para bus I2C
#include <Adafruit_GFX.h> // libreria para pantallas graficas
#include <Adafruit_SSD1306.h> // libreria para controlador SSD1306
#define ANCHO 128 // reemplaza ocurrencia de ANCHO por 128
#define ALTO 64 // reemplaza ocurrencia de ALTO por 64
#define OLED_RESET 4 // necesario por la libreria pero no usado
Adafruit_SSD1306 oled(ANCHO, ALTO, &Wire, OLED_RESET); // crea objeto
volatile int value;
volatile int lastEncoded = 0;
int A = 2; //variable A a pin digital 2 (DT en modulo)
int B = 4; //variable B a pin digital 4 (CLK en modulo)
int m =8;
int cont;
float volt;
void setup()
{
EEPROM.get(0, value);
Wire.begin(); // inicializa bus I2C
oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); // inicializa pantalla con direccion 0x3C
pinMode(9,OUTPUT);
pinMode(A, INPUT); // A como entrada
pinMode(B, INPUT); // B como entrada
digitalWrite(A, HIGH);
digitalWrite(B, HIGH);
pinMode(m,INPUT);
//Endable Interrupts for PCIE2 arduino Pins (D0-7)
PCICR |= (1<<PCIE2);
//Setup pins 2,4
PCMSK2 |= (1<<PCINT18);
PCMSK2 |= (1<<PCINT20);
TCCR1A = _BV(COM1A1) | _BV(WGM11);
TCCR1B = _BV(CS10) | _BV(WGM12) | _BV(WGM13) ;
ICR1 = 250; // frequency = 16000000/ = 64.000 kHz
sei();
}
void loop()
{
oled.clearDisplay(); // limpia pantalla
oled.setTextColor(WHITE); // establece color al unico disponible (pantalla monocromo)
oled.setCursor(10, 20); // ubica cursor en inicio de coordenadas 0,0
oled.setTextSize(3); // establece tamano de texto en 1
oled.print(volt); // escribe en pantalla el texto
oled.display(); // muestra en pantalla todo lo establecido anteriormente
energia();
duty();
voltimetro();
}
ISR (PCINT2_vect) {
int MSB = digitalRead(A);
int LSB = digitalRead(B);
int encoded = (MSB << 1) |LSB;
int sum = (lastEncoded << 2) | encoded;
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011)
value++;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000)
value--;
lastEncoded = encoded;
if (value <= 0)
value = 0;
if (value >= 255)
value = 255;
}
void duty() {
OCR1A = value;
}
void energia (){
if(digitalRead(m)==LOW){
cont++;
delay(3);
if (cont >5) {
EEPROM.put(0,value);
delay(50);
cont = 0;
}
}
}
void voltimetro(){
volt=value;
Ahí subí las fotos para que se me entienda mejor, simular un voltimetro, con un contador ascendente y descendente de 0 a 5 volt o de 0 a 18 volt , ahí me trabe no se como hacerlo!