Go Down

Topic: a programar um mux 8:1 problemas nas portas de saida (Read 1 time) previous topic - next topic

bruguink

Boas Pessoal,
o que me trás aki é o seguinte, estou a a fazer um programa que me permita comandar as portas de selcção de um  mux de 8:1(dm 74151an). para os que estão mais dentro do funcionamento do mux, ele uma 3pinos que fazem a selecção da entrada que está a ser lida. no meu programa atraves da porta serie consigo ver isso a acontecer mas quando ligo 3 leds aos pinos do arduino que me fazem essa selecção nada me acontece. não estou a conseguir com que as saidas digitais liguem esse leds com a sequencia que implementei.
vou deixar ai o meu codigo pra vcs darem uma vista de olhos a verem se descobrem onde errei.

Code: [Select]
int sensorPin = A0; // pino analogico por onde irá receber os valores dos sensores
int sensorValue = 0; // variavel q armazena o valor lido pelo A0


int r0 = 0; // valor do pino (s0) do 4051
int r1 = 0; // s1
int r2 = 0; // s2

int count = 0; // contador



void setup()
{
 
 
 
 
  pinMode(5, OUTPUT); // define o pino digital 2 como saida s0
  pinMode(6, OUTPUT); // s1
  pinMode(7, OUTPUT); // s2
 
  Serial.begin(9600); // inicia a comunicação serie
}


void loop()
{
  for ( count=0; count<=7; count++)
  {
   
    r0 = bitRead(count,0);
    r1 = bitRead(count,1);
    r2 = bitRead(count,2);
   
    Serial.print("r0");
    Serial.print(r0);
    Serial.print("r1");
    Serial.print(r1);
    Serial.print("r2");
    Serial.print(r2);
   
   
    digitalWrite(5, r0);
    digitalWrite(6, r1);
    digitalWrite(7, r2);
   
    sensorValue = analogRead(sensorPin); //a varialvel fica com valor lido pino A0
    float voltage = sensorValue * (5.0 / 1023.0);
    Serial.print("sensor"); // escreve sensor
    Serial.print(count+1); // correspondente ao sensor que está a ser lido entre sensor0 a sensor 7
 
    Serial.print("=");
    Serial.print(voltage);
    Serial.println("volts");
 
    delay (2000);
  }
}

bruguink

a minha duvida é, será que qd faço digitalWrite(5,ro) essa saída D5 fica com 5v qd r0=1 e 0v quando r0=0? será que essa função faz isso?

Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

bruguink

eu já utilizei o mux, mas não tive resultados lógicos. portanto nesta fase estou a testar as saidas digitais do arduino atraves de leds, que estão ligados a essas mesmas saidas, mas não estou a conseguir que eles acendam....acho que com o codigo que apresentei, isso deveria acontecer não é verdade, em q atraves dos leds deveria  conseguir ver a evolução da" tabela de verdade" que faz selecionar todas as entradas do mux.

HugoPT

#4
Jan 30, 2013, 12:36 am Last Edit: Jan 30, 2013, 12:43 am by HugoPT Reason: 1
[  pinMode(5, OUTPUT); // define o pino digital 2 como saida s0
 pinMode(6, OUTPUT); // s1[/quote]
Não estarás a confundir os pinos !
Aqui estas a dizer que queres o pino 5 da placa como saída mas no comentario pensas que e a saída 2!
Outra coisa o que pretendes nesse ciclo for em ler os bits da variável que usas como contador?
Não entendo ...
Debian,Mint,Ubuntu
Arduino Mega 2560
Arduino Nano
Arduino Duemilanove
MAC OS Montain Lion
Raspberry PI Model B

bruguink

ok...estou a usar o arduino nano, em que os pinos 5,6 e 7 da placa correspondem ás i/o digtais d2,d3,d4 respectivamente.
ou seja serão etas saidas que irei utilizar para mapear as entradas do mux, 8 entradas para uma saída.

o ciclo "for" serve para correr todas essas entradas do mux, por isso que vai de 0...7.
o que eu faço no codigo com a função bitRead:

ele lê o valor da variavel count em binario
0=000
1=001
2=010
.
.
.
7=111

por isso qd faço
    r0 = bitRead(count,0);------>lê o 1º bit e guarda em r0
    r1 = bitRead(count,1);------>lê o 2º bit e guarda em r1
    r2 = bitRead(count,2);------>lê o 3º bit e guarda em r2


é com este ciclo que vou repruduzir a tabela de verdade para correr todas as entradas do mux ,em que a as saidas d2,d3,d4 que corresponde aos pinos 5,6,7 da placa ficarão com o valor das variaveis r0,r1,r2..

HugoPT

Mas colega tu estas a carregar isso num int que sao 2 bytes(16bits) e depois mandas escrever no pino esse valor todo!
Quote
r0 = bitRead(count,0);
    r1 = bitRead(count,1);//r1 é sao 2 bytes
    r2 = bitRead(count,2);

A funçao digitalWrite só aceita como argumentos o pino e o valor que pode ser LOW ou HIGH
Quote
Syntax

digitalWrite(pin, value)

Parameters

pin: the pin number

value: HIGH or LOW

Returns

none


O que esperas que aconteça aqui:
Code: [Select]
digitalWrite(5, r0);//r0 é um int que tentas escrever num bit do porto!
    digitalWrite(6, r1);
    digitalWrite(7, r2);

Code: [Select]
  for ( count=0; count<=7; count++)
  {
   
    r0 = bitRead(count,0);
    r1 = bitRead(count,1);
    r2 = bitRead(count,2);

O resultado final disto vai ser:
r0 = 0;//Em binario é 0b00000000;
r1= 1;//Em binario é 0b00000001;
r2= 2;//Em binario é 0b00000010;
Mas isso acontece internamente nao precisas de correr esse for para atribuires isso!
Fazeres r2 = 2 é a mesma coisa que r2= 0b00000010;


Debian,Mint,Ubuntu
Arduino Mega 2560
Arduino Nano
Arduino Duemilanove
MAC OS Montain Lion
Raspberry PI Model B

Nada como simplificar ainda mais o teste...

Faz um sketch assim:

Code: [Select]

setup(){

pinMode(5, OUTPUT);

}

loop(){
digitalWrite(5, 1);
delay(2000);
digitalWrite(5,0);
delay(2000);
}


O pino que estiver a pulsar é o pino 5 e será o que tem um D5 ao lado e não o 5º pino da placa (que é o D2).
A plataforma está feita para que se alguém quiser usar uma saída apenas tem de ver o que diz na placa e não contar pinos. Na placa original isto é um pouco mais evidente devido ao formato esquisito. Numa placa com este formato entendo a confusão que faz.

Experimenta o que disse e vê no que dá.

A propósito, essa lógica para actuar os controlos do mux está muito bem conseguido... no entanto, podes fazer "melhor"

Se vais usar os pinos 2,3 e 4 da placa, que são na realidade os pinos PD2, PD3 e PD4 podes fazer algo assim:

Code: [Select]

unsigned char count;
for(count = 0 ; count<8 ; count ++){  //count tem o valor do canal que queres ler.
  unsigned char temp = (count<<2);  //desvias esse valor dois bits para a esquerda
  PORTD = temp;                             // e o bit 0 de count está agora no PD2. :)
}


Isto torna o código um pouco mais rápido de executar. No entanto, se já estiveres a usar os pinos do PORTD isto estraga tudo... para resolveres esse imbróglio, podes fazer assim:

Code: [Select]

unsigned char count;
for(count = 0 ; count<8 ; count ++){  //count tem o valor do canal que queres ler.
  unsigned char temp = (count<<2);  //desvias esse valor dois bits para a esquerda
  unsigned char mask = PORTD & 0b11100011; //Ler todos os bits menos os três que queremos mudar
  PORTD = temp | mask;                             //
}


Onde vês o estado das saídas e voltas a escrever o mesmo valor lá.

@Hugo

Code: [Select]


//in Arduino.h
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))


#define HIGH 0x1
#define LOW  0x0

//in wiring_digital.h

void digitalWrite(uint8_t pin, uint8_t val)
{
uint8_t timer = digitalPinToTimer(pin);
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *out;

if (port == NOT_A_PIN) return;

// If the pin that support PWM output, we need to turn it off
// before doing a digital write.
if (timer != NOT_ON_TIMER) turnOffPWM(timer);

out = portOutputRegister(port);

uint8_t oldSREG = SREG;
cli();

if (val == LOW) {
*out &= ~bit;
} else {
*out |= bit;
}

SREG = oldSREG;
}

Ou seja, o bitRead apenas retorna 0 ou 1.

a variável count e rx vão ser algo como:

count = 0; r0 = 0; r1 = 0; r2 = 0;
count = 1; r0 = 1; r1 = 0; r2 = 0;
count = 2; r0 = 0; r1 = 1; r2 = 0;
count = 3; r0 = 1; r1 = 1; r2 = 0;
count = 4; r0 = 0; r1 = 0; r2 = 1;

Como o valor 1 cabe num unsigned char (que é o uint8_t), não há problema nenhum em fazer como ele faz.
Acho que o que deve estar a acontecer é mesmo uma confusão nos pinos. Nada como actuar cada um deles individualmente para tirar isso a limpo. :)
Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

HugoPT

Code: [Select]
Ou seja, o [b]bitRead apenas retorna 0 ou 1.
[/b]
a variável count e rx vão ser algo como:

count = 0; r0 = 0; r1 = 0; r2 = 0;
count = 1; r0 = 1; r1 = 0; r2 = 0;
count = 2; r0 = 0; r1 = 1; r2 = 0;
count = 3; r0 = 1; r1 = 1; r2 = 0;
count = 4; r0 = 0; r1 = 0; r2 = 1;

Bem visto escapou me esse promenor
Debian,Mint,Ubuntu
Arduino Mega 2560
Arduino Nano
Arduino Duemilanove
MAC OS Montain Lion
Raspberry PI Model B

Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

Go Up