Sida 2 av 3

Re: PISO 74HC165 till arduino ger opålitlig data

Postat: 15 april 2016, 18:55:40
av Castor
Vad händer om du lägger alla höga?

Re: PISO 74HC165 till arduino ger opålitlig data

Postat: 15 april 2016, 19:15:46
av Icecap
74HC ger bättre nivåer än HCT så det delen er OK.

Men jag funderar lite på varför CE ens är kopplat till en pinne. I min värld ska det ske en läsning (LD -> aktiv -> inaktiv) varefter det ska shiftas in 8 bit. Jag har inte läst databladet så det kan finnas anledning men rent logisk kan jag inte se den.

Re: PISO 74HC165 till arduino ger opålitlig data

Postat: 15 april 2016, 20:22:40
av rvl
minuzed skrev:Så länge ALLA inputs är jordade via 10k så visar den 0b0000 0000 men så fort jag antingen drar någon till VCC så ballar den ur. Det funkar heller inte att bara jorda någon input direkt till GND för då flippar den precis som om dom vore flytande.
Inkluderar dethär daisy chain ingången? (DS)

En sak jag kom att tänka på är om kapcitivt kopplad nätspänning kan tänkas hitta till kretsen. Ett PC nätaggregat i ett ojordat uttag kan ställa till vissa överraskningar. Hade en gång en pulsräknare till en tryckknapp, som i teorin endera borde varit låg eller hög ...men i det ena läget stod räknaren still och meddelade korrekt polaritet medan den i andra läget räknade räknaren vilt.

Ett felsökningssteg kunde vara att mata Arduinon från en laptop som kör från sitt batteri utan galvanisk kopling till elnätet, eller andra trådnät.

Re: PISO 74HC165 till arduino ger opålitlig data

Postat: 15 april 2016, 22:10:59
av baron3d
Tänk på att om du kopplar en switch till klock så kommer den att reagera på alla kontaktstudsarna. I videon använder han en liten konding för att dämpa kontaktstudsarna.
Eftersom du har kopplat DS till "0" så borde q7 ge "0" efter 8 klockpulser.
Det skulle vara av intresse och veta exakt hur du kopplat när du styr kretsen med switchar.

Re: PISO 74HC165 till arduino ger opålitlig data

Postat: 16 april 2016, 10:45:42
av minuzed
Va trevligt att så många engagerar sig :) riktigt kul med all respons som ni ger, det uppskattas!
Castor skrev:Vad händer om du lägger alla höga?
Om jag lägger alla höga med 10k motstånd så blir det fladder, lägger jag dom höga direkt till VCC blir det oxå fladder.
Icecap skrev:74HC ger bättre nivåer än HCT så det delen er OK. Men jag funderar lite på varför CE ens är kopplat till en pinne. I min värld ska det ske en läsning (LD -> aktiv -> inaktiv) varefter det ska shiftas in 8 bit. Jag har inte läst databladet så det kan finnas anledning men rent logisk kan jag inte se den.
CE (clock enable) har många kopplat direkt till GND (aktiv låg) men jag kopplade den till en pinne för kunna ha kontroll över den. Jag drar den låg (aktiv) så fort jag gjort läsningen och låter den vara det tills jag skiftat ut alla 8-bitarna och drar sen den hög (inaktiv) igen. Jag har provat att alltid ha den aktiv till GND och det blir ingen skillnad i resultatet.
rvl skrev:Inkluderar dethär daisy chain ingången? (DS)
Eftersom jag inte använder DS och det är en input så har jag lagt den låg med ett 220R motstånd för att den inte ska vara flytande. Jag tror heller inte att det blir någon skillnad om jag skippar motståndet och drar den direkt till GND. Jag har fler 165or som jag hade tänkt koppla ihop senare men det känns ganska långt borta innan jag ens har fått EN att fungera :P
rvl skrev:Ett felsökningssteg kunde vara att mata Arduinon från en laptop som kör från sitt batteri utan galvanisk kopling till elnätet, eller andra trådnät.
Testade nyss att driva den från USB-porten på en laptop på enbart batteridrift, samma fladder när alla inputs är höga.
baron3d skrev:Det skulle vara av intresse och veta exakt hur du kopplat när du styr kretsen med switchar.
Det jag egentligen gjort nu är bara att sätta en switch på en av mina inputs för att enkelt kunna göra den hög. Jag har då satt en 100nF keramisk kondensator parallellt med switchen i hopp om att minska studsandet. Jag har även testat med två olika elektrolyter, en 100uF och en 10uF, även detta gav ingen skillnad. Så länge jag håller nere switchen och gör inputen hög (aktiv) så ger det fladder.

En grej jag har upptäckt nu är att all inputs fladdrar samtidigt. Dvs alla inputs visas som höga, vid nästa läsning visas alla som låga och vid någon enstaka gång visas ca dom första 4 bitarna en sak och dom sista visar motsatsen.

Re: PISO 74HC165 till arduino ger opålitlig data

Postat: 16 april 2016, 10:54:50
av Jan Almqvist
Jag tror att du ska leta efter fel i programmet.

Edit: För att ta bort kontaktstuds tror jag på att använda bara kondensator räcker utan det behövs väl åtminstone RC-nät + schmitt-trigger?

Re: PISO 74HC165 till arduino ger opålitlig data

Postat: 16 april 2016, 10:57:14
av sodjan
Är "fladdret" kontinuerligt eller enbart då en switch ställs om?

> vid nästa läsning...

En timme senare? Eller efter hur lång tid?

> Dvs alla inputs visas som höga,
> vid nästa läsning visas alla som låga
> och vid någon enstaka gång visas ca dom första 4 bitarna en sak och dom sista visar motsatsen.

Alltid just *dessa* tre alternativ? Alltså inte helt slumpmässigt?

Det är också intressant att veta hur koden ser ut *för just det du beskriver*.

Re: PISO 74HC165 till arduino ger opålitlig data

Postat: 16 april 2016, 11:26:19
av minuzed
sodjan skrev:Är "fladdret" kontinuerligt eller enbart då en switch ställs om?
En timme senare? Eller efter hur lång tid?
Fladdret sker alltid medan någon (oavsett vilken) av mina inputs är höga.
Läsningen sker i en oändlig loop men den skriver bara ut i min seriella monitor när den förändring har skett i förhållande mot föregående läsning.

Rent statistiskt skulle jag nog påstå att den till 95% växlar mellan att läsa alla inputs som samtidigt höga/låga och vid enstaka fall kan den läsa en blandning av bitarna så blandningen kan vara tillfälligheter.

Koden ser ut så här:

Kod: Markera allt

/* How many shift register chips are daisy-chained.
*/
#define NUMBER_OF_SHIFT_CHIPS   1

/* Width of data (how many ext lines).
*/
#define DATA_WIDTH   NUMBER_OF_SHIFT_CHIPS * 8

/* Width of pulse to trigger the shift register to read and latch.
*/
#define PULSE_WIDTH_USEC   5

/* Optional delay between shift register reads.
*/
#define POLL_DELAY_MSEC   1

/* You will need to change the "int" to "long" If the
 * NUMBER_OF_SHIFT_CHIPS is higher than 2.
*/
#define BYTES_VAL_T unsigned int

int ploadPin        = 31;  // Connects to Parallel load pin the 165
int clockEnablePin  = 30;  // Connects to Clock Enable pin the 165
int dataPin         = 50; // Connects to the Q7 pin the 165
int clockPin        = 52; // Connects to the Clock pin the 165

BYTES_VAL_T pinValues;
BYTES_VAL_T oldPinValues;

/* This function is essentially a "shift-in" routine reading the
 * serial Data from the shift register chips and representing
 * the state of those pins in an unsigned integer (or long).
*/
BYTES_VAL_T read_shift_regs()
{
    long bitVal;
    BYTES_VAL_T bytesVal = 0;

    /* Trigger a parallel Load to latch the state of the data lines,
    */

    digitalWrite(ploadPin, LOW);          // Pull PL low (active) and high (inactive) to load the parallel data into the register
    delayMicroseconds(PULSE_WIDTH_USEC);
    digitalWrite(ploadPin, HIGH);
    delayMicroseconds(PULSE_WIDTH_USEC);
    
    digitalWrite(clockEnablePin, LOW);    // Enable clock CE
    delayMicroseconds(PULSE_WIDTH_USEC);

    /* Loop to read each bit value from the serial out line
     * of the SN74HC165N.
    */
    for(int i = 0; i < DATA_WIDTH; i++)
    {
        bitVal = digitalRead(dataPin);

        /* Set the corresponding bit in bytesVal.
        */
        bytesVal |= (bitVal << ((DATA_WIDTH-1) - i));

        /* Pulse the Clock (rising edge shifts the next bit).
        */
        digitalWrite(clockPin, HIGH);
        delayMicroseconds(PULSE_WIDTH_USEC);
        digitalWrite(clockPin, LOW);
    }

    digitalWrite(clockEnablePin, HIGH);   // Done reading data, disable clock
    
    return(bytesVal);
}

/* Dump the list of zones along with their current status.
*/
void display_pin_values()
{
    Serial.print("Pin States:\r\n");

    for(int i = 0; i < DATA_WIDTH; i++)
    {
        Serial.print("  Pin-");
        Serial.print(i);
        Serial.print(": ");

        if((pinValues >> i) & 1)
            Serial.print("HIGH");
        else
            Serial.print("LOW");

        Serial.print("\r\n");
    }

    Serial.print("\r\n");
}

void setup()
{
    Serial.begin(9600);

    /* Initialize our digital pins...
    */
    pinMode(ploadPin, OUTPUT);
    pinMode(clockEnablePin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, INPUT);

    digitalWrite(clockPin, LOW);          // Active high
    digitalWrite(ploadPin, HIGH);         // Active low
    digitalWrite(clockEnablePin, HIGH);   // Active low

    /* Read in and display the pin states at startup.
    */
    pinValues = read_shift_regs();
    display_pin_values();
    oldPinValues = pinValues;
}

void loop()
{
    /* Read the state of all zones.
    */
    pinValues = read_shift_regs();

    /* If there was a chage in state, display which ones changed.
    */
    if(pinValues != oldPinValues)
    {
        Serial.print("*Pin value change detected*\r\n");
        display_pin_values();
        oldPinValues = pinValues;
    }

    delay(POLL_DELAY_MSEC);
}

Jag har en idé. Jag skriver ett nytt program med ny kod. Detta programmet ska enbart sköta 2 pin; CP (clock) och PL (parallel load). Programmets syfte kommer bara vara att agera som switchar för dessa två pinnar för att jag ska slippa studsar med mekaniska switchar. Alla inputs kommer kopplas direkt till GND eller VCC. CE (clock enable) och DS (serial input) kommer jag ansluta direkt till GND och Q7 (serial output) kommer jag koppla till en LED via ett lämpligt motstånd. Jag kommer även ansluta en LED via ett lämpligt motstånd till CP för att kunna se när klockan är aktiv. Programmet kommer även att arbeta med ett högt delay mellan varje steg (minst 1 sek) för att jag ska hinna se den seriella datan på Q7-LEDen som då ska indikera de olika bitarnas läge medan jag skiftar ut registret.

Detta borde ge mig så lite kod som möjligt som kan gå fel då det endast ger hög eller låg signal på CP och PL. Initialt kommer PL hållas hög. När läsning ska se kommer den göra PL låg (aktiv) i en sek och sedan hög (inaktiv) igen. Efter detta kommer den med en sekunds mellanrum att växla CP hög och låg för att klocka ut registret via Q7 som förhoppningsvis ska visa läget på mina input när PL var aktiv.

Re: PISO 74HC165 till arduino ger opålitlig data

Postat: 16 april 2016, 12:17:27
av sodjan
Helt rätt! Förenkla och förenkla tills felet hittas... :-)

Re: PISO 74HC165 till arduino ger opålitlig data

Postat: 16 april 2016, 12:26:43
av Icecap
Först och främst behövs ingen delay för att läsa bit'sen! 74HC165 överträffar långt ATmega'n i hastighet.

Sedan har jag en avsky för Arduinons sätt att hantera I/O men det är min smak.

Allt du ska göra är att slå Latch-pinnen aktiv och sedan inaktiv.
Sedan ska du läsa utgången från 165'an och mata in i LSB på en byte-variabel.
Ge en klock-signal (-> aktiv, sedan -> inaktiv).
Läs nästa osv, totalt 8 gånger.

Detta kan göras i full hastighet utan problem, att vänta i 3 evigheter innan varje läsning ger inget.

Re: PISO 74HC165 till arduino ger opålitlig data

Postat: 16 april 2016, 12:42:53
av SeniorLemuren
En liten men kanske dum fråga: Har du satt monitorn på 9600 baud. Jag brukar glömma det ofta och då blir det ju kajko.

Re: PISO 74HC165 till arduino ger opålitlig data

Postat: 16 april 2016, 12:49:26
av minuzed
Det är lika självklart att den är snabbare än min uC som att den borde fungera normalt :P
I ett färdigt steg så ska jag givetvis kunna utnyttja hastigheten men eftersom den inte beter sig som förväntat så försöker jag istället sakta ner och förenkla processen så att jag har en rimlig chans att kunna upptäcka vad som orsakar mina märkliga resultat.

Jag har ett par gamla hederliga ATmega8 liggandes som jag skulle kunna testa att göra samma sak med men eftersom jag för tillfället inte använder arduinon till mer än att växla PL-pinnen och clock-signalen så borde det kvitta vilken uC jag använder. Just nu använder jag den som sagt bara för att jag tyckte detta var det enklaste sättet att komma undan studs från mekaniska switchar.
SeniorLemuren skrev:En liten men kanske dum fråga: Har du satt monitorn på 9600 baud. Jag brukar glömma det ofta och då blir det ju kajko.
Jepp jag kör den på 9600 och monitorn på samma ;)

Re: PISO 74HC165 till arduino ger opålitlig data

Postat: 16 april 2016, 13:06:05
av minuzed
Äntligen beter den sig som förväntat! :D
LEDen på min serial out visar rätt värden när jag shiftar ut registret och ändrar jag någon av mina inputs så registrerar den det vid nästa PL cykel.
Jaha då är det bara att börja koda om från början och försöka få in den seriella datan i datorn och sen öka tempot så får vi se var nästa överraskning kommer :lol:

För den som kan vara intresserad så ser min nya (och än så länge fungerande) kod ut så här:

Kod: Markera allt

// Setup pins

const int internalLEDPin = 13; // This pin will control the on-board LED
const int plPin = 31; // This pin will control the parallel load
const int cpPin = 33; // This pin will control the clock pin

void setup() {
  // put your setup code here, to run once:
  pinMode(internalLEDPin, OUTPUT);
  pinMode(plPin, OUTPUT);
  pinMode(cpPin, OUTPUT);
  
  digitalWrite(internalLEDPin, LOW); // LED off
  digitalWrite(plPin, HIGH);  // This is active LOW so I set this inactive for now
  digitalWrite(cpPin, LOW);   // This is active HIGH so I set this inactive for now
}

void loop() {
  // put your main code here, to run repeatedly:
  load_parallel_data_into_register();
  shift_out_data_to_LED();
  
}

void load_parallel_data_into_register()
{
  digitalWrite(plPin, LOW);   // Pull PL low (active) to load parallel data into the register

  // Blink the on-board LED 2 times to show that we set PL active
  for(int i = 0; i < 2; i++) {
    digitalWrite(internalLEDPin, HIGH);
    delay(250);
    digitalWrite(internalLEDPin, LOW);
    delay(250);
  }

  digitalWrite(plPin, HIGH);  // Pull PL high (inactive) so we can shift out the register
  delay(1000);                // Wait for 1 sec
}

void shift_out_data_to_LED()
{
  // Send 8 clock-signals to CP to shift out the register
  for(int i = 0; i < 8; i++) {
    digitalWrite(cpPin, HIGH);          // Activate clock-signal
    digitalWrite(internalLEDPin, HIGH); // Turn on on-board LED to show that we are sending clock-signals
    delay(1000);                        // Wait for 1 sec
    digitalWrite(cpPin, LOW);           // Deactivate clock-signal
    digitalWrite(internalLEDPin, LOW);  // Turn on-board LED off
    delay(1000);                        // Wait for 1 sec
  }

  // Show that all data has been shifted out by lighting the on-board LED for 5 secs
  digitalWrite(internalLEDPin, HIGH);
  delay(5000);
  digitalWrite(internalLEDPin, LOW);
  delay(1000);
}

Re: PISO 74HC165 till arduino ger opålitlig data

Postat: 16 april 2016, 13:28:06
av sodjan
Va bra! Ja, i ett läge där det ändå inte fungerar så är det kanske lite onödigt
att börja snacka om att man kör *för* långsamt. Det går att köra den kretsen
precis hur långsamt som helst, till och med så att man hinner mäta på
signalerna manuellt eller visa signalerna med LEDs...

I din testkod så kör du alltså i princip bara klocksignalerna, du läser
inte in resultatet alls (?).

Sannolikt har din föregående kod någon liten bugg någonstans.

Re: PISO 74HC165 till arduino ger opålitlig data

Postat: 16 april 2016, 13:42:21
av minuzed
Helt rätt, jag triggar PL så att den tar ett "snapshot" av portarna och sänder sedan klocksignalerna. Det är det enda den gör. Den tar ingen input alls, den läser jag manuellt ut genom att se om min externa LED (som är ansluten till Q7/serial out på 74HC165) lyser eller inte vid varje puls av klocksignalen.

Föregående kod har jag kopierat från arduinos playground och sedan anpassat den efter vilka pinnar jag har använt. När inte det funkade började jag ändra i koden men utan framsteg. Jag tycker dock att den koden borde fungera för jag ser inga direkta konstigheter i den. Jag får bygga upp min kod ifrån detta som fungerar och lägga till varje moment för sig tills dess att det börjar balla ur igen. På så sätt lär jag förhoppningsvis hitta vad som orsakat all denna huvudbry :lol: