Go Down

Topic: Intercettare change di tutti i PORT PinChangeInt (Read 1 time) previous topic - next topic

pablos

#15
Dec 14, 2012, 12:21 pm Last Edit: Dec 14, 2012, 02:52 pm by pablos Reason: 1
Ci sono vicino ho applicato il pezzo di Lesto per trovare i bit cambiati e funziona, ma ottengo un numero in uscita sbagliato

Code: [Select]

//--------------------timer--------------------------------------------------------
unsigned long previousMillis_e = 0;  
unsigned long interval_e = 50;
//---------------------------------------------------------------------------------
byte Port[] = {0,0,0,0,0,0,0,0,0}; //A,B,C,D,E,G,H,J,L  ... valori hold
byte cont; // contatore per pulsante port 32(test)

void setup()
{
 delay(1000);
 Serial.begin(9600);//debug
 pinMode(32, INPUT);
 DDRL = 255;  // set a OUTPUT i pin 42-43-44-45-46-47-48-49
 //PORTL = 0;  // metto a LOW i pin 42-43-44-45-46-47-48-49
}

void loop()
{  
 unsigned long currentMillis_e = millis();
 if(currentMillis_e - previousMillis_e > interval_e)
 {  
       previousMillis_e = currentMillis_e;            

   if(Port[2] !=  PINC){
   byte C[] = {30,31,32,33,34,35,36,37};
   BitChange(Port[2], PINC, C);  
   Port[2] =  PINC;
   Serial.println("CHANGE PORT_C 30-31-32-33-34-35-36-37 >> val byte = " + (String)PINC );//debug    
   }
 
   /*if(Port[3] != PIND){
   Serial.println("CHANGE PORT_D 18-19-20-21-38 >> val byte = " + (String)PIND);//debug
   }*/
 
   if(Port[5] !=  PING){
   Port[5] =  PING;
   Serial.println("CHANGE PORT_G 39-40-41-4  >> val byte = " + (String)PING);//debug
   }
 
   if(Port[8] !=  PINL){
   byte L[] = {42,43,44,45,46,47,48,49};
   BitChange(Port[8], PINL, L);
   Port[8] =  PINL;  
   Serial.println("CHANGE PORT_L 42-43-44-45-46-47-48-49 >> val byte = " + (String)PINL );//debug
   }  
       
//----------------------test con pulsante-----------------------      
       if (digitalRead(32)) cont++; else cont=0;
   
       if (digitalRead(42) == 0 && cont == 1){                
         PORTL |= (1<<7); cont++;
       }
       
       if (digitalRead(42) == 1 && cont == 1){              
         PORTL &= ~(1<<7); cont++;
       }      
//------------------------------------------------------------------    
}
}

void BitChange(byte Hold_Val_Port, byte New_Val_Port, byte Pin[])
{
  byte Cambio = New_Val_Port ^ Hold_Val_Port;
 
      for ( byte i=0; i < 8; i++)
      {
        if ( Cambio & (1<<(8-i)))  //controllo lo stato del bit in posizione 8-i            
        Serial.print("Il pin " + (String)Pin[i] + " e' cambiato! ...  ");//debug   <<<<<<<<<<<< ERRORE!!!
      }  
}  
 


ricapitolando ho:
Un pulsante sul pin 32 quindi PORTC
Un led sul pin 42 quindi PORTL

premo il pulsante e lo rilascio immediatamente

se metto
Code: [Select]

Serial.print("Il pin " + (String)Pin[i] + " e' cambiato! ...  ");


ottengo questa uscita
Il pin 33 e' cambiato! ...  CHANGE PORT_C 30-31-32-33-34-35-36-37 >> val byte = 32   <<< ERRORE
Il pin 43 e' cambiato! ...  CHANGE PORT_L 42-43-44-45-46-47-48-49 >> val byte = 128  <<< ERRORE
Il pin 33 e' cambiato! ...  CHANGE PORT_C 30-31-32-33-34-35-36-37 >> val byte = 0     <<< ERRORE

----------------------------------------------------


se metto ivece -1 pensavo di correggere entrambi i valori
Code: [Select]

Serial.print("Il pin " + (String)Pin[i-1] + " e' cambiato! ...  ");


ottengo invece questa uscita
Il pin 31 e' cambiato! ...  CHANGE PORT_C 30-31-32-33-34-35-36-37 >> val byte = 32   <<< ERRORE
Il pin 42 e' cambiato! ...  CHANGE PORT_L 42-43-44-45-46-47-48-49 >> val byte = 128 <<< GIUSTO
Il pin 31 e' cambiato! ...  CHANGE PORT_C 30-31-32-33-34-35-36-37 >> val byte = 0    <<< ERRORE


Perchè??? dannazione  :smiley-sweat:


Tabella dal file pins_arduino.h - Pin definition functions for Arduino

PL   , // PL 7 ** 42 ** D42   
PL   , // PL 6 ** 43 ** D43   
PL   , // PL 5 ** 44 ** D44   
PL   , // PL 4 ** 45 ** D45   
PL   , // PL 3 ** 46 ** D46   
PL   , // PL 2 ** 47 ** D47   
PL   , // PL 1 ** 48 ** D48   
PL   , // PL 0 ** 49 ** D49

PC   , // PC 7 ** 30 ** D30   
PC   , // PC 6 ** 31 ** D31   
PC   , // PC 5 ** 32 ** D32   
PC   , // PC 4 ** 33 ** D33   
PC   , // PC 3 ** 34 ** D34   
PC   , // PC 2 ** 35 ** D35   
PC   , // PC 1 ** 36 ** D36   
PC   , // PC 0 ** 37 ** D37      
no comment

pablos

#16
Dec 14, 2012, 02:24 pm Last Edit: Dec 14, 2012, 02:52 pm by pablos Reason: 1
Risolto, grazie per le idee e l'aiuto


Code: [Select]
void BitChange(byte Hold_Val_Port, byte New_Val_Port, byte Pin[])
{
  byte Cambio = New_Val_Port ^ Hold_Val_Port;
 
      for ( byte i=0; i < 8; i++)
      {        
        if ( Cambio & 1<<i)  //controllo lo stato del bit in posizione 8-i        
        Serial.print("Il pin " + (String)Pin[i] + " e' cambiato! ...  BIT n = " + (String)i + " ");//debug                
      }  
}  


byte C[] = {30,31,32,33,34,35,36,37};
diventa
byte C[] = {37,36,35,34,33,32,31,30};

byte L[] = {42,43,44,45,46,47,48,49};
diventa
byte L[] = {49,48,47,46,45,44,43,42};
--------------------------------------------------------------------

risposta di debug prima pressione e rilascio

Il pin 32 e' cambiato! ...  BIT n = 5 CHANGE PORT_C 37,36,35,34,33,32,31,30 >> val byte = 32
Il pin 42 e' cambiato! ...  BIT n = 7 CHANGE PORT_L 49,48,47,46,45,44,43,42 >> val byte = 128
Il pin 32 e' cambiato! ...  BIT n = 5 CHANGE PORT_C 37,36,35,34,33,32,31,30 >> val byte = 0

risposta di debug seconda pressione e rilascio
Il pin 32 e' cambiato! ...  BIT n = 5 CHANGE PORT_C 37,36,35,34,33,32,31,30 >> val byte = 32
Il pin 42 e' cambiato! ...  BIT n = 7 CHANGE PORT_L 49,48,47,46,45,44,43,42 >> val byte = 0
Il pin 32 e' cambiato! ...  BIT n = 5 CHANGE PORT_C 37,36,35,34,33,32,31,30 >> val byte = 0

no comment

leo72

Quindi serviva invertire l'ordine dei pin negli array.

pablos

#18
Dec 14, 2012, 02:31 pm Last Edit: Dec 14, 2012, 02:34 pm by pablos Reason: 1
si cambiare l'ordine e modificare il confronto, stampando il debug del for mi si è evidenziato l'errore

da
if ( Cambio & (1<<(8-i)))

a
if ( Cambio & 1<< i)

ho ridotto inoltre il debounce da 100ms a 50ms
no comment

lesto

ahhah lol e pensare che mi sono sbattuto apposta a fare (8-i) per invertire le uscite in base alla maschera :)
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

pablos

#20
Dec 14, 2012, 08:52 pm Last Edit: Dec 14, 2012, 08:54 pm by pablos Reason: 1
Guarda lascia perdere, nel sistemare lo sketch mi sono accorto che l'errore su PORTC era casusato da
byte C[] = {30,31,31,33,34,35,36,37};

Non ho ancora provato, ma con Pin[i-1] e if ( Cambio & (1<<(8-i))) +  l'array corretto sono quasi certo che funzionava lo stesso

Grazie il tuo intervento e' stato utilissimo

ciao
no comment

pablos

Leo me la fai una libreria interceptor su tutti i gruppi PORT?
Mgari la chiami LeoPORTAvia ... LeoPORC ahahahah chiamala come ti pare ... ti va?
Ti prendi anche i diritti GPL GAS ENI  a me non interessa :)
Io non son buono, sei tu l'esperto mastro libraio  ]:D

ciao
no comment

leo72


Leo me la fai una libreria interceptor su tutti i gruppi PORT?
Mgari la chiami LeoPORTAvia ... LeoPORC ahahahah chiamala come ti pare ... ti va?
Ti prendi anche i diritti GPL GAS ENI  a me non interessa :)
Io non son buono, sei tu l'esperto mastro libraio  ]:D

ciao

Che libreria ti devo fare?  :smiley-sweat:

pablos

Siccome non è possibile avere tutti i pin della mega (70pin I/O) collegati internamente a degli interrupt, sarebbe possibile creare nel loop un richiamo in background per leggere le variazioni dei PORT con relativa uscita dei pin cambiati?
Chiaramente prendendo spunto dallo sketch completo che ho fatto.
Penso che faresti felice molti utenti che hanno progetti domo e altri progetti dove deve essere controllata l'attività I/O dell'MCU.
A parte scherzi io te l'ho buttata li, se hai tempo, voglia e ritieni sia il caso secondo me può essere utile per un certo tipo di automazione.

ciao
no comment

leo72


Siccome non è possibile avere tutti i pin della mega (70pin I/O) collegati internamente a degli interrupt, sarebbe possibile creare nel loop un richiamo in background per leggere le variazioni dei PORT con relativa uscita dei pin cambiati?
Chiaramente prendendo spunto dallo sketch completo che ho fatto.
Penso che faresti felice molti utenti che hanno progetti domo e altri progetti dove deve essere controllata l'attività I/O dell'MCU.
A parte scherzi io te l'ho buttata li, se hai tempo, voglia e ritieni sia il caso secondo me può essere utile per un certo tipo di automazione.

ciao

Non ho capito qual'è la differenza fra il codice che hai usato tu e la libreria PinChangeInterrupt che è già fatta (e che mi pareva di aver linkato in precedenza).

pablos

Perchè solo 20 pin possono supportare gli interrupt.
Io lo faccio esternamente su 54 pin.
Tra quelli supportati ci sono i pin 10-11-12-13 50-51-52-53 usati dallo shield Ethernet e SD.

Ma non mi serve la lib scherzavo, ma la  PinChangeInt library for the Arduino non fa al caso mio
no comment

leo72


Perchè solo 20 pin possono supportare gli interrupt.

Ah, ora capisco.

Quote
Io lo faccio esternamente su 54 pin.
Tra quelli supportati ci sono i pin 10-11-12-13 50-51-52-53 usati dallo shield Ethernet e SD.

Ma non mi serve la lib scherzavo, ma la  PinChangeInt library for the Arduino non fa al caso mio

Pablos, lo puoi fare anche tu. Prendi il leOS2, e metti in un task il codice per controllare il cambio di stato dei pin usando l'algoritmo che hai elaborato. Basta quindi che ad ogni chiamata del task tu faccia la fotografia di tutti i pin e se quello per cui è stato attivato un interrupt SW ha cambiato di stato chiami una routine.

Go Up
 

Quick Reply

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.

Note: this post will not display until it's been approved by a moderator.
Name:
Email:

shortcuts: alt+s submit/post or alt+p preview