¿Alguien se aclara con Arduino y C?

Taller de hardware y cacharreo general de aparatos eléctricos y electrónicos que no tengan un sitio propio.
Avatar de Usuario
scooter
Amiga 1200
Amiga 1200
Mensajes: 1029
Registrado: 17 Jul 2012, 09:25
primer_sistema: C64
Ubicación: Alicante

¿Alguien se aclara con Arduino y C?

Mensajepor scooter » 06 Ene 2013, 10:55

Estoy haciendo un proyecto con Arduino y salen algunos resultados no esperados.
¿Es aquí buen sitio para preguntar o mejor en otro subforo?

En el foro de Arduino de momento parecen no saber.

Avatar de Usuario
mrcomputer
Atari 1040 STf
Atari 1040 STf
Mensajes: 897
Registrado: 15 Abr 2008, 14:45
Sistema Favorito: Commodore Amiga
Primera consola: Nintendo GameBoy

Re: ¿Alguien se aclara con Arduino y C?

Mensajepor mrcomputer » 06 Ene 2013, 12:05

¿Lo estas haciendo desde el IDE de arduino o directamente a pelo AVR C?

Saludos
Tienda de cables retro
http://www.retrocables.es

Avatar de Usuario
mentalthink
Amiga 2500
Amiga 2500
Mensajes: 2840
Registrado: 11 Abr 2010, 15:06
Gracias dadas: 45 veces
Gracias recibidas: 14 veces

Re: ¿Alguien se aclara con Arduino y C?

Mensajepor mentalthink » 06 Ene 2013, 14:00

Hola yo de C putro y duro no lo he probado pero desde el lenguaje suyo propio no le veo una gran complicación... Si te puedo ayudar en algo coméntamelo...
Aunque no estoy seguro puedes meterle C++ directamente aunque estés programando en el modo "normal" o sea desde el IDE de el mismo...

Saludetes!!!

Avatar de Usuario
scooter
Amiga 1200
Amiga 1200
Mensajes: 1029
Registrado: 17 Jul 2012, 09:25
primer_sistema: C64
Ubicación: Alicante

Re: ¿Alguien se aclara con Arduino y C?

Mensajepor scooter » 06 Ene 2013, 16:32

Lo hago desde el IDE del arduino pero accediendo a algunas cosas del hard directamente.

Un par de notas previas:
De programar en C estoy pez; pese a haberlo intentado en las últimas décadas nunca lo he "interiorizado" osea que es probable que tenga errores muy muy básicos.
Programar en código máquina si que se, lo he hecho durante años en varias plataformas.


El problema:
Mediante interrupciones para cargar lo mínimo la CPU hago lo siguiente. Un sensor hall manda un pulso que activa una salida y un tiempo después se apaga. Ambas señales van por interrupciones; una externa para inicio y una por el timer2 para el final. Parece funcionar correctamente, pero al haber añadido unas instrucciones para contar el tiempo de la amplitud del pulso salen tiempos muy grandes.
No he podido medir la amplitud real del pulso y puede que sea correcta y el "medidor" con lafunción millis() o con micros() da mas o menos lo mismo no mida bien porque las funciones del sistema sean muy lentas.
El caso es que el tiempo mínimo son 16mS y debería de ser menos.

El código:

Código: Seleccionar todo

    #include <avr/interrupt.h>
    #include <avr/io.h>
    int Inyector = 3;    //
    int LED = 13;        //Pin del led
    int PotOn=A0;
    int recarga=100;
    int RPM;
    unsigned long tOn=0;
    unsigned long tOnOld;
    unsigned long apertura;
    volatile int state = LOW;
    //
   
    ISR(TIMER2_OVF_vect) {
    digitalWrite( Inyector, LOW);
//Parar el timer 2
    TCCR2B &= ((0<<CS22) | (0<<CS21) | (0<<CS20));
    //TIMSK2 |= (0<<TOIE2) ;  //InHabilita interrupción por desbordamiento del Timer2
    apertura=millis()-tOn;
    state = !state;
    Serial.print("R=");
    Serial.print(recarga);
    Serial.print("  Ap=");
    Serial.print(apertura);
    Serial.print("mS ");
    Serial.print(RPM);
    Serial.println("rpm");
    };
    void setup() {
    //Parar el timer 2
    TCCR2B &= ((0<<CS22) | (0<<CS21) | (0<<CS20));     
    // Use normal mode
    TCCR2A |= (0<<WGM21) | (0<<WGM20);
    // Usar reloj interno. No se usa el reloj externo en arduino
    ASSR |= (0<<AS2);
    TIMSK2 |= (1<<TOIE2) | (0<<OCIE2A);  //Habilita interrupción por desbordamiento del Timer2
    //Initialize serial and wait for port to open:
    Serial.begin(9600);
    // prints title with ending line break
    Serial.println("ECU 004 (c) Felix Diaz");

      // initialize the digital pin as an output.
  pinMode(Inyector, OUTPUT); 
  pinMode (LED  , OUTPUT);
   attachInterrupt(0, inicio, FALLING); //Puede ser LOW, CHANGE, RISING Y FALLING
    }

    void loop() {
        recarga=255-analogRead(PotOn)/4;    //El potenciometro va al revés que el timer
          digitalWrite(LED, state);
        delay(100);
    }

void inicio()
{
  digitalWrite( Inyector, HIGH);
  tOnOld=tOn;
  tOn=millis();
  sei();
  //Recargar el timer:
    TCNT2=recarga;
    //Configuración del timer 2: Preescaler /1024,
    TCCR2B |= ((1<<CS22) | (1<<CS21) | (1<<CS20));
    //Resetear el preescaler
    GTCCR |= (1<<PSRASY);
  RPM=60000/(tOn-tOnOld);
}


Dado lo taruguín que soy programando en C, a ver si veis algún error gordo o algo. Es probable que tenga alguna orejada tonta.

Otra idea que he tenido es usar otro arduino para leer lo que hace este, pero si es que no hacen bien el cálculo del tiempo lo mismo va a dar.

Creo que el medidor va bien; he estado generando pulsos a mano de 1Hz y el medidor de rpm da 60 que es lo correcto, osea que parece que por algún motivo desconocido se tarda 16ms adicionales en ejecutar una interrupción, y 16ms en un animalito que va a 16MHz son una eternidad o dos.

Me huele a que no inicializo bien las interrupciones o algo semejante y que hace un ciclo completo de 256 en el timer que corresponden a los 16ms y después ya hace el ciclo programado con lo que sea. Por eso varía entre 16 y unos 32ms. Pero realmente no se donde está la cuestión. Debería de durar entre "cero" y 16ms. Cero no podrá ser pero vamos, casi cero y 16ms.

Avatar de Usuario
mentalthink
Amiga 2500
Amiga 2500
Mensajes: 2840
Registrado: 11 Abr 2010, 15:06
Gracias dadas: 45 veces
Gracias recibidas: 14 veces

Re: ¿Alguien se aclara con Arduino y C?

Mensajepor mentalthink » 06 Ene 2013, 18:11

Ostis... y yo te comento desde mi humilde opinión, si con el C estás un poco oxídado, por no usas directamente el lenguaje de Arduino, seguramente haya librerias para el tema de interrupciones.. de hecho hay para muchísimas cosas, aunque no vengan en la lista de la página de Arduino (a mi parecer está más que obsoleta, de hecho el foro ya no existe.. al menos el español).

PS: Te recomiendo el IDE de Visual Basic, con un plugin gratuito que hay... está Eclipse y una versión especial de Code Blocks, que tiene un simulador de Arduino... pero sinceramente me quedo con el de Visual Studio 2012... No sé eso de que en el IDE normal veas las funciones en una lista al lado, no llego a acostumbrarme..

Avatar de Usuario
scooter
Amiga 1200
Amiga 1200
Mensajes: 1029
Registrado: 17 Jul 2012, 09:25
primer_sistema: C64
Ubicación: Alicante

Re: ¿Alguien se aclara con Arduino y C?

Mensajepor scooter » 06 Ene 2013, 20:45

Eso es el lenguaje del arduino, no es C pero se le parece que apesta, de hecho yo no lo distingo del C.
Hay ciertas funciones que están soportadas y otras que no, por ejemplo no lo están las interrupciones de los timers y yo es que no puedo vivir sin ellas y no entiendo como se puede hacer nada decente sin usarlas.

Si que hay foro español, y se mueve algo pero no parecen saber del tema, me tendré que hacer el ánimo de formular las preguntas en inglés.

-- Actualizado 07 Ene 2013, 01:44 --

Bueno, asunto resuelto.
He buscado otra página de la que copiar código. La primera estaba plagada de fallos.
La cuestión era algo del orden de escritura en los registros, me parece.

El código que si que funciona:

Código: Seleccionar todo

    #include <avr/interrupt.h>
    #include <avr/io.h>
    int Inyector = 3;    //
    int LED = 13;        //Pin del led
    int PotOn=A0;
    byte recarga=100;
    int RPM;
    boolean rebote = false;
    unsigned long tOn=0;
    unsigned long tOff=0;
    unsigned long tOnOld;
    unsigned long apertura;
    unsigned int escrituras=0;
    volatile int state = LOW;
    //
   
    ISR(TIMER2_OVF_vect) {
    tOff=millis();
    rebote = false;
      digitalWrite( Inyector, LOW);
//Parar el timer 2
    TCCR2B = 0;  //Parar el timer 2
    //TIMSK2 = 0 ;  //InHabilita interrupción por desbordamiento del Timer2
    apertura=tOff-tOn;
    state = !state;
    Serial.print("E=");
    Serial.print(escrituras);
    Serial.print(" R=");
    Serial.print(recarga);
    Serial.print("  Ap=");
    Serial.print(apertura);
    Serial.print("mS ");
    Serial.print(RPM);
    Serial.println("rpm");
    };
    void setup() {
    rebote = false;
    //Initialize serial and wait for port to open:
    Serial.begin(9600);
    // prints title with ending line break
    Serial.println("ECU 005 (c) Felix Diaz");
    // initialize the digital pin as an output.
    pinMode(Inyector, OUTPUT); 
    pinMode (LED  , OUTPUT);
    attachInterrupt(0, inicio, FALLING); //Puede ser LOW, CHANGE, RISING Y FALLING
    }

    void loop() {
        recarga=255-analogRead(PotOn)/4;    //El potenciometro va al revés que el timer
          digitalWrite(LED, state);
        delay(100);
    }

void inicio()
{
  if (rebote == false){
  tOnOld=tOn;
  tOn=millis();
  digitalWrite( Inyector, HIGH);
  //Setup Timer2 to fire every 1ms
  TCCR2B = 0x00;        //Disbale Timer2 while we set it up
  TCNT2  = recarga;         //Reset Timer Count to 130 out of 255
  TIFR2  = 0x00;        //Timer2 INT Flag Reg: Clear Timer Overflow Flag
  TIMSK2 = 0x01;        //Timer2 INT Reg: Timer2 Overflow Interrupt Enable
  TCCR2A = 0x00;        //Timer2 Control Reg A: Wave Gen Mode normal
  TCCR2B = 0x07;        //Timer2 Control Reg B: Timer Prescaler set to 1024

  RPM=60000/(tOn-tOnOld);
  rebote = true;
  ++escrituras;
  //
}
}


Gracias a los que habéis intervenido; cuando uno se atasca cualquier cosa sirve de apoyo y ánimo para seguir.


Volver a “Taller general”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 2 invitados