Op 27 juli 2020 11:54:38 schreef buckfast_beekeeper:
[...]
Nu volg ik even niet.
byte_1 komt in de array: columns_byte_1
byte_2 komt in de array: columns_byte_2
byte_3 komt in de array: columns_byte_3
henri62
1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.
Je had toch 24 receivers (vertikaal) direct aan de pins van een controller hangen?
Dan kun je toch direct de 3 poorten uitlezen en heb je 3 bytes = 24 bits, niks te shiften/decoderen.
Misshien dat de bits niet helemaal exact mappen op je poorten en moet je misschien wat bits omwisselen maar dat is ook niet zo schokkend.
In je ISR lees je eerst alle 3 poorten direct achter elkaar (om geen timeshift te krijgen) in 3 lokale variablen, daarna stop je die 3 bytes in een array die de horizontale as voorstelt. Als je hele scan van tig meter gedaan is stuur je de bytes op naar je andere CPU. Of je doet dat parallel (in je main loop) op een getimede trigger van de CPU waar het naar toe moet.
Je hebt dan een horizontale baan van alle pixels.
Voor elk bordje van 24 pixels heb je dan een baantje die je later in je "hoofd" CPU weer aan elkaar plakt.
-edit- Ach, crap: Je wilde die dingen vertikaal scannen om geen strooilicht te kijgen.
Dan zou ik gewoon een teller maken van 0-23 en het bit/byte uitrekenen wat je in moet vullen.
Ik ga er even vanuit dat het bovenste bit 0 is en byte ook
Wat pseudo code:
// Globale variablen
// Tabel met poortnummers
uint8_t portname[3] = { portA, portB, portC};
// main loop die iedere scan triggerd
// Erase bytes, moet voor elke scan van 24 bits
for (int i= 0; i < 3; i++ ) {
array[0] = 0;
}
int row = 0;
ISR(TIMER1_COMPA_vect)
{
bytenum = row % 3; // Hier komt 0,1,2 uit als index van de poorten.
bit = row & 0x07; // Hier komt 0-7 uit voor het bit uit de betreffende poort.
port = portname[row]; // haal het poort nummer op.
// Lees de hardware port en maskeer het juiste bitje
uint8_t readmask = readport(port) & (1 << bit);
// Voeg bitje samen met al eerder gelezen bits
array[bytenum] |= readmask;
// Volgende row
row++;
}
Zit er ergens wat gespiegeld moet je misschien de poort assignment in de tabellen omdraaien of het bitmask omdraaien maar dat is simpel.
Er moet ergens nog wat synchronisatie worden toegevoegd om iedere scan de boel te triggeren.
Maar eigenlijk heb je geen ISR nodig. In jouw geval is er een tegenoverliggende print die de IR leds van boven naar beneden aanstuurt daarmee moet de ontvanger precies gesynchroniseerd worden.
Welke controller doet dat aansturen? Ik neem aan je hoofprocessor die alle borden straks leest?
Trigger je nu maar 1-malig ieder bord (per 24 bits) en laat je dan de zender en ontvanger op vrijloop de boel inlezen?
Als je dat doet krijg je straks wat fading effecten en moet je een kleine dode tijd tussen het zenden/inlezen bouwen. Of in het midden van de IR zenderpuls een sample nemen. DWZ als de zender 4ms de led aanzet moet je op de ontvanger na 2ms beginnen te lezen en dan de intervallen 4ms maken.
Op 27 juli 2020 20:54:53 schreef henri62:
Trigger je nu maar 1-malig ieder bord (per 24 bits) en laat je dan de zender en ontvanger op vrijloop de boel inlezen?
Als je dat doet krijg je straks wat fading effecten en moet je een kleine dode tijd tussen het zenden/inlezen bouwen. Of in het midden van de IR zenderpuls een sample nemen. DWZ als de zender 4ms de led aanzet moet je op de ontvanger na 2ms beginnen te lezen en dan de intervallen 4ms maken.
nog niet alles volledig en begrijpend gelezen, maar dit hierboven is exact
hoe het nu gaat.
ik zal morgen eens de volledige code posten.
volledige code:
onderstaande is getest met 3x array waar vaste waardes in stonden, dus het verzenden van de atmega 32 naar de atmega 2560 gaat wel goed.
lukt nu alleen niet om de status v/d input pinnen over te sturen.
edit: net nog eens getest met een array met vaste waardes daar in, en dit werkt correct.
probleem volgens mij is dat de byte_1 byte_2 en byte_3 niet goed in de array worden gezet.
//*** 28-7-2020 ******************************************************************************************
// TESTING THE RS485 UART TSOP ***************************************************************************
// fuse: ext. crystal/resonater medium freq. start up 16 64
// fuse: J-tag uitvinken
#define F_CPU 8000000UL // 8 MHz clock speed
#include <stdio.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
int receivedbyte = 0;
int bytetosend = 0;
int column_counter_byte_1 = 0;
int column_counter_byte_2 = 0;
int column_counter_byte_3 = 0;
int byte_1 = 0;
int byte_2 = 0;
int byte_3 = 0;
uint8_t PulseCounter = 150;
uint8_t BitCounter = 0;
volatile start_scan = 0;
int start_send_data_byte_1 = 0;
int start_send_data_byte_2 = 0;
int start_send_data_byte_3 = 0;
int shift_byte_out = 0;
uint8_t columns_byte_1 [300];
uint8_t columns_byte_2 [300];
uint8_t columns_byte_3 [300];
ISR(TIMER1_COMPA_vect)
{
static uint8_t PulseCounter = 150;
static uint8_t BitCounter = 0;
if(PulseCounter == 0)
{
PulseCounter = 150;
switch(BitCounter++)
{
case 0 : { byte_1 |= (PINC & 0x80); PORTD |= (1 << PIND3); break;}
case 1 : { byte_1 |= (PINC & 0x40); break; }
case 2 : { byte_1 |= (PINC & 0x20); break; }
case 3 : { byte_1 |= (PINC & 0x10); break; }
case 4 : { byte_1 |= (PINC & 0x08); break; }
case 5 : { byte_1 |= (PINC & 0x04); break; }
case 6 : { byte_1 |= (PINC & 0x02); break; }
case 7 : { byte_1 |= (PINC & 0x01);
if(column_counter_byte_1 < sizeof(columns_byte_1) )
{
columns_byte_1 [column_counter_byte_1] = byte_1;
column_counter_byte_1 += 1;
}
break;
}
case 8 : { byte_2 |= (PINA & 0x80); PORTD |= (1 << PIND4); PORTD &= ~(1 << PIND3); break; }
case 9 : { byte_2 |= (PINA & 0x40); break; }
case 10: { byte_2 |= (PINA & 0x20); break; }
case 11: { byte_2 |= (PINA & 0x10); break; }
case 12: { byte_2 |= (PINA & 0x08); break; }
case 13: { byte_2 |= (PINA & 0x04); break; }
case 14: { byte_2 |= (PINA & 0x02); break; }
case 15: { byte_2 |= (PINA & 0x01);
if(column_counter_byte_2 < sizeof(columns_byte_2) )
{
columns_byte_2 [column_counter_byte_2] = byte_2;
column_counter_byte_2 += 1;
}
break;
}
case 16: { byte_3 |= (PINB & 0x80); PORTD |= (1 << PIND7); PORTD &= ~(1 << PIND4); break; }
case 17: { byte_3 |= (PINB & 0x40); break; }
case 18: { byte_3 |= (PINB & 0x20); break; }
case 19: { byte_3 |= (PINB & 0x10); break; }
case 20: { byte_3 |= (PINB & 0x08); break; }
case 21: { byte_3 |= (PINB & 0x04); break; }
case 22: { byte_3 |= (PINB & 0x02); break; }
case 23: { byte_3 |= (PINB & 0x01);
if(column_counter_byte_3 < sizeof(columns_byte_3) )
{
columns_byte_3 [column_counter_byte_3] = byte_3;
column_counter_byte_3 += 1;
}
break;
}
// below: pulse counter = 0; needed so that TSAL & TSOP number 1 start on the same time.
case 24:
{
PORTD &= ~(1 << PIND7);
BitCounter = 0;
PulseCounter = 0;
start_scan = 0;
break;
}
} // from: switch
} // from: if(PulseCounter == 0)
else
{
PulseCounter -= 1;
}
} // from: ISR
ISR(TIMER1_COMPB_vect) // 38 khz
{
PORTB = 0;
PORTA = 0;
PORTC = 0;
}
int main(void)
{
DDRA = 0b00000000;
PORTA = 0b11111111;
DDRB = 0b00000000;
PORTB = 0b11111111;
DDRC = 0b00000000;
PORTC = 0b11111111;
DDRD = 0b11111110; // PD0 = RXD
// PORTD = 0b00000001;
sei();
TCCR1B |= (1 << WGM12); // CTC-mode,
TIMSK |= (1 << OCIE1A) | (1 << OCIE1B) ; // timer1 A & B compare match interrupt enabled
OCR1A = 209;
OCR1B = 100;
UCSRA = (1 << MPCM); // enable: multi processor communication mode
UCSRB = (1 << RXEN) | (1 << TXEN)| (1 << UCSZ2); // Turn on the transmission and reception circuit
UCSRC = (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // 9-bit mode, URSEL bit for selecting UCSRC
UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register
UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
for(;;)
{
while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been received and is ready to be read from UDR
receivedbyte = UDR; // Fetch the received byte value into the variable "ReceivedByte"
//*** adress numbering: TSAL 1-20 and TSOP 21-40 *******************************************************
if (receivedbyte == 21) // adress byte
{
UCSRA &=~(1 << MPCM); // make MPCM "0"
while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been received and is ready to be read from UDR
receivedbyte = UDR; // Fetch the received byte value into the variable "ReceivedByte"
if (receivedbyte == 0b11110000) // is the data byte: start your scan
{
_delay_ms(3); // to make we look in the middle off the TSAL pulse
start_scan = 1;
column_counter_byte_1 = 0; // 0, so that the first saved byte comes on 0 in the array
column_counter_byte_2 = 0;
column_counter_byte_3 = 0;
}
if (receivedbyte == 0b00000001) // is the data byte: send the data 1e byte to the master
{
_delay_ms(5);
start_send_data_byte_1 = 1;
}
if (receivedbyte == 0b00000010) // is the data byte: send the data 2e byte to the master
{
_delay_ms(5);
start_send_data_byte_2 = 1;
}
if (receivedbyte == 0b00000011) // is the data byte: send the data 3e byte to the master
{
_delay_ms(5);
start_send_data_byte_3 = 1;
}
while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been received and is ready to be read from UDR
receivedbyte = UDR; // Fetch the received byte value into the variable "ReceivedByte"
if (receivedbyte == 0b11111111) // is the stop byte
{
UCSRA = (1 << MPCM); // enable: multi processor communication mode
}
}
//********** TSOP ****************************************************************************************
while (start_scan == 1)
{
TCCR1B |= (1 << CS10); // start timer with prescaler = 0
// PORTA = byte_1; // for testing ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
if (start_scan == 0)
{
TCCR1B &= ~(1 << CS10); // stop timer with prescaler = 0
byte_1 = 0; // waarschijnlijk alleen voor testen^^^^^^^^^^^^^^^^^^
}
while (start_send_data_byte_1 == 1)
{
PORTD |= (1 << PIND3); // for checking rood = "1" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PORTD |= (1 << PIND2); // switch MAX485 as transmitter pin 2 & 3 = "1"
for (shift_byte_out = 0; shift_byte_out < 302; shift_byte_out ++) //test ^^^^^^^^^^^^^^
{
while ((UCSRA & (1 << UDRE)) == 0) {}; // do nothing till the UDR is ready to receive
bytetosend = columns_byte_1[shift_byte_out];
UDR = bytetosend;
}
start_send_data_byte_1 = 0;
PORTD &= ~(1 << PIND3); // for checking rood = "0" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
while (start_send_data_byte_2 == 1)
{
PORTD |= (1 << PIND4); // // for checking geel = "1" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PORTD |= (1 << PIND2); // switch MAX485 as transmitter pin 2 & 3 = "1"
for (shift_byte_out = 0; shift_byte_out < 302; shift_byte_out ++)
{
while ((UCSRA & (1 << UDRE)) == 0) {}; // do nothing till the UDR is ready to receive
bytetosend = columns_byte_2[shift_byte_out];
UDR = bytetosend;
}
start_send_data_byte_2 = 0;
PORTD &= ~(1 << PIND4); // for checking geel = "0" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
while (start_send_data_byte_3 == 1)
{
PORTD |= (1 << PIND7); // for checking groen = "1" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PORTD |= (1 << PIND2); // switch MAX485 as transmitter pin 2 & 3 = "1"
for (shift_byte_out = 0; shift_byte_out < 302; shift_byte_out ++)
{
while ((UCSRA & (1 << UDRE)) == 0) {}; // do nothing till the UDR is ready to receive
bytetosend = columns_byte_3[shift_byte_out];
UDR = bytetosend;
}
start_send_data_byte_3 = 0;
PORTD &= ~(1 << PIND7); // for checking groen = "0" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
if (start_send_data_byte_3 == 0)
{
PORTD &= ~(1 << PIND2); // switch MAX485 as receiver pin 2 & 3 = "0"
}
} // from: for (;;)
} // from: main
henri62
1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.
Zo te zien is er niets die de werkelijke scan loop start?
Hoe had je dat in gedachten hoe dat zou moeten werken?
Maak eerst eens een simpel diagram of wat eisen wat elk systeem/cpu board precies zou moeten doen, want zo ga je er niet uit komen.
Ik stel me dit voor:
Je hebt N zender borden die ieder 24 IR zenders hebben.
Je hebt N ontvanger borden die ieder 24 IR ontvangers hebben.
Elk zender board moet synchroon lopen met zijn ontvanger (of andersom).
Elk zender board zal van beneden naar boven elke van de 24 leds aansturen en de ontvanger moet die bits synchroon inlezen (dit om strooilicht te voorkomen).
Als je een complete vertikale scan doet wil je dat ieder board 24 pixels inleest en dat dit parallel/tegelijk gebeurd.
Na een scan van 24 pixels per board heb je een complete scan van N x 24 pixels en die wil je in een centrale processor ontvangen.
Afgaande uit de gegevens van vorige posts kom ik tot de conclusie dat een led uitlezen ca 4ms duurt, dus een complete scan van EEN bordje (en dus in totaal ALLE vertikale borden) zal dus ca 24*4ms = 96 ms duren.
Hieruit kun je dus afleiden dat de hoofd processor alle borden dus op een tick van minimaal 96 ms moet triggeren om alles te scannen.
Om alle data over te sturen van N borden moet je dus N x 24/8 bytes ruim binnen het budget van 96 ms moeten kunnen versturen.
Stel N=10 geeft dit jouw 300 bytes.
Als je uitgaat van een mechanisme dat elk board zijn eigen request binnen krijgt om zijn data te sturen (vanuit de hoofdprocessor) heb je snel minimaal 2 bytes voor de request nodig (adres, commando) + wat delay, zeg maar 3 bytes * 10 bits => 30 bits. (10 bits=start bit, 8 data bits, stop bit)
De data moet dan terug gestuurd worden ook nog eens minimaal 4 bytes. => 40 bits.
Dus totaal voor alle borden 10 *(30+40) = 700 bits.
Dus je baudrate moet dan minimaal 96 ms / 700 = 137 us => 7300 baud moeten zijn en dan moet echt alles perfect op elkaar afgestemd zijn. Ik zou dan minimaal op 19200 baud of hoger gaan zitten.
Wil je dus volcontinue scannen kun je de data die je opstuurd in een ISR versturen en "tegelijk" je volgende row scannen.
Je hebt ook nog die trigger vanuit je hoofdprocessor nodig om de scan's van ieder board te triggeren, dat kun je doen door een commando naar het RS485 broadcast adres te sturen, dat is "by convention" adres 0. Dit is vaak in een CPU configureerbaar dat je ook via je UART data binnen krijgt op adres 0 naast wat je zelf in je adres match register zet. Alle borden starten dat exact gelijk met je scan opdracht.
Ik schrijf dit verhaal boven omdat de clou van het verhaal is dat je in de main loop eigenlijk alleen moet wachten op ontvangst van de trigger van de hoofdprocessor: Je zet wat variabelen klaar en wacht op het START-SCAN commando (op het broadcast adres). Dan start je de juiste timers en die doen de rest.
Dit doe je in beide borden zowel de ontvanger as de zender. Alleen zit er in de zender de code die de leds aanstuurt en in de ontvanger code die de ontvangers uitleest.
In je main loop wacht je dan tot de 24 scan pulsen gemaakt zijn en het feestje begint opnieuw voor de volgende trigger vanuit je hoofdprocessor.
Het verhaal wordt complexer als je echt het onderste uit de kan wilt halen.
In de ontvanger kun je het best ook een double buffer mechanisme inbouwen: Terwijl je de ene rij leds inleest heb je een ander buffertje die je verzend naar de hoofdprocessor die het vorige "sample" uitleest in de 96 ms die het duurt om een nieuwe scan te maken. Vandaar dat ik ook uitgelegd heb wat je tijds-budget is om een hele rij van leds uit te lezen.
bovenstaande is wanneer je meteen de data naar de hoofd controller stuurt tijdens het scannen, maar dat doe ik niet, ik sla alle data v/d scans eerst op in de atmega 32.
en later als alle scans klaar zijn vraagt de hoofd controller aan iedere atmega 32 om zijn data naar de hoofdcontroller te sturen, op deze manier word het allemaal niet zo tijd kritisch, nadeel is dat het later versturen wel extra tijd kost.
- hoofd controller stuurt alleen een start comando naar de zend en de ontvang PCB. (0b11110000 in mijn prog) vanaf daar gebeurt de scan in de zend & ontvang controller.
- vervolgens gaan de zend & ontvang PCB de 24 led's 1 voor 1 af. (over 24 led's zal de synchronisatie niet verlopen).
- werkstuk schuift 10 mm op en de hoofdcontroller stuurt weer enkel en alleen een start comando naar de zend & ontvanger.(werkstuk beweegt continu)
- dat doet ie in totaal 300x en de scan is klaar. zo zit er in elke atmega32 v/d ontvanger 3x300 = 900 bytes,
- tenslotte vraagt de hoofd controller aan elke atmega 32 v/d ontvanger, stuur mij je data. in het geval van 10 borden is dat dus 10 x 900 = 9000 byte.
dit is denk ik de meest simpele manier om dit te doen, wat wel voor verbetering vatbaar is natuurlijk, vooral in tijdswinst.
Op 27 juli 2020 10:39:04 schreef trix:
hallo,ik heb hier een stukje code dat ik probeer te doorgronden, ik heb dat niet zelf bedacht, maar dekees heeft dat voor mij gemaakt.
ik kan de topic waarin hij dat heeft gepost niet meer terug vinden, vandaar een nieuw topic.
Deze ? : https://www.circuitsonline.net/forum/view/150417?query=dekees&mode…
henri62
1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.
Zowiezo lijkt hier ook iets niet pluis:
while (start_scan == 1)
{
TCCR1B |= (1 << CS10); // start timer with prescaler = 0
// PORTA = byte_1; // for testing ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
Hier wordt continue de prescaler gezet, dat wil je maar een keer doen en dan wachten op het einde van de 24 scan pulsen.
Die while() hoort iets later te zitten en triggeren op een conditie die ergens in de ISR hoort te zitten.
PS Wat doet dit hier?:
ISR(TIMER1_COMPB_vect) // 38 khz
{
PORTB = 0;
PORTA = 0;
PORTC = 0;
}
[Bericht gewijzigd door henri62 op (12%)]
moet ik nog eens bekijken, de scan in het zender gedeelt is hetzelfde qua opbouw, en dat werkt 100 % zeker.
@shiptronic, nee dat is een andere topic.
Op 28 juli 2020 20:47:23 schreef henri62:
PS Wat doet dit hier?: [code] ISR(TIMER1_COMPB_vect) // 38 khz { PORTB = 0; PORTA = 0; PORTC = 0; }
timer1 staat in CTC mode (clear to compare match).
met: ISR(TIMER1_COMPA_vect) word de freqentie v/d "draag freq."
OCR1A = 209 (clk = 8 MHz) dit geeft ong. 38kHz.
met: ISR(TIMER1_COMPB_vect) word de puls lengt bepaald. is ong. de helft (50% duty cycle).
ik heb nu een software fout ontdekt in mijn op zet waardoor een en ander niet goed kan werken.
voor het voorbeeld neem ik 1x IR zender (TSAL) en 1x IR ontvanger (TSOP) die fysiek tegen over elkaar staan.
hoe het nu is:
- de zender stuurt 4mS lang de TSAL aan.
- de ontvanger kijk 4mS lang of hij licht of donker is (1 of 0)
daar begint hij mee op het midden v/d TSAL puls (heb ik zo geprogd)
maar dat betekent dat hij na het einde v/d TSAL pulse nog steeds 2 mS
kijkt of hij licht of donker is. dit geeft foutieve waardes.
hoe het moet zijn:
- de zender stuurt 4mS lang de TSAL aan.
- de ontvanger kijkt dan van 1 tot 3 mS of hij licht of donker is.
maar ik zie even niet hoe ik dit in de geposte code moet aanpassen ? het start moment op 1mS is geen probleem (heb ik nu ook al (op 2mS)) maar het stop moment bij 3 mS is wel een probleem.
kan iemand mij hier mee op weg helpen ?
bedankt.
Op 28 juli 2020 20:47:23 schreef henri62:
PS Wat doet dit hier?:ISR(TIMER1_COMPB_vect) // 38 khz { PORTB = 0; PORTA = 0; PORTC = 0; }
ik denk dat je hier gelijk had, en dat dit hier niet thuis hoort (in tegenstelling tot wat ik later beweerde)
klopt nog meer niet inde code, ben zoekende 
in de code test ik alleen met poort C. poort A misbruik ik om de LA aant te sturen.
ondanks dat nu mijn "kijk" moment in de IR ontvanger (TSOP) goed is, krijg ik nog steeds niet de data in de array.
nog even zoeken/testen dus.
dit is een deel v/d code.
uint8_t columns_byte_1 [300]; // geblokt voor te testen ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
uint8_t columns_byte_2 [300]; // geblokt voor te testen ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
uint8_t columns_byte_3 [300]; // geblokt voor te testen ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ISR(TIMER1_COMPA_vect)
{
static uint8_t PulseCounter = 150;
static uint8_t BitCounter = 0;
if(PulseCounter == 0)
{
PulseCounter = 150;
// - Lokale variabelen zijn weer weg als de ISR is afgelopen
// - Of je moet ze static declareren zoals de PulseCounter hierboven
TCNT0 = 0; // is the start moment from the 2 mS (length of puls)
PORTA |= (1 << PINA0);
check_bit = 1;
switch(BitCounter++)
{
case 0 : { byte_1 |= ((PINC & 0x80) & (check_bit == 1)); PORTA |= (1 << PINA7); PORTD |= (1 << PIND3); break;}
case 1 : { byte_1 |= ((PINC & 0x40) & (check_bit == 1)); PORTA |= (1 << PINA6); break; }
case 2 : { byte_1 |= ((PINC & 0x20) & (check_bit == 1)); PORTA |= (1 << PINA5); break; }
case 3 : { byte_1 |= ((PINC & 0x10) & (check_bit == 1)); PORTA |= (1 << PINA4); break; }
case 4 : { byte_1 |= ((PINC & 0x08) & (check_bit == 1)); PORTA |= (1 << PINA3); break; }
case 5 : { byte_1 |= ((PINC & 0x04) & (check_bit == 1)); PORTA |= (1 << PINA2); break; }
case 6 : { byte_1 |= ((PINC & 0x02) & (check_bit == 1)); PORTA |= (1 << PINA1); break; }
case 7 : { byte_1 |= ((PINC & 0x01) & (check_bit == 1));
if(column_counter_byte_1 < sizeof(columns_byte_1) )
{
columns_byte_1 [column_counter_byte_1] = byte_1;
column_counter_byte_1 += 1;
}
break;
}
// below: pulse counter = 0; needed so that TSAL & TSOP number 1 start on the same time.
case 24:
{
PORTD &= ~(1 << PIND7);
BitCounter = 0;
PulseCounter = 0;
start_scan = 0;
break;
}
} // from: switch
} // from: if(PulseCounter == 0)
else
{
PulseCounter -= 1;
}
} // from: ISR
ISR(TIMER1_COMPB_vect) // 38 khz
{
PORTB = 0;
// PORTA = 0; //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PORTA &= ~(1 << PINA7); // for testing ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PORTA &= ~(1 << PINA6); // for testing ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PORTA &= ~(1 << PINA5); // for testing ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PORTA &= ~(1 << PINA4); // for testing ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PORTA &= ~(1 << PINA3); // for testing ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PORTA &= ~(1 << PINA2); // for testing ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PORTA &= ~(1 << PINA1); // for testing ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PORTC = 0;
}
ISR(TIMER0_COMP_vect) // needed for making the TSOP looking for 2 mS
{
PORTA &= ~(1 << PINA0);
check_bit = 0;
}
[Bericht gewijzigd door trix op (16%)]
hallo,
ik heb hetgeen wat niet werkt terug gebracht tot het stukje code wat niet werkt.
case 7 : { byte_1 |= ((PINC & 0x01) & (check_bit == 1));
check_bit is het moment dat ik naar de IR ontvanger (TSOP) kijk of deze "1" of "0" is. (in mijn getekend plaatje (paar posts terug) de 2mS die ik nu terug gebracht heb naar 0,5 mS).
de status moet in byte_1 worden geplaatst, zonder de overige bits te veranderen. die doe ik uiteindelijk 8x zodat de byte_1 volledig gevuld is.
dit werkt niet, nu had ik een paar vragen:
- PINC & 0x01 moet dat niet PORTC & 0x01
- is & juist of moet dat && zijn tussen (PINC & 0x01) en (check_bit == 1)
ik heb bovenstaande al wel getest maar zonder resultaat.
wie ziet er wat er wellicht niet goed is, mijn dank is groot, want ik zie het voorlopig niet 
nog even getest, en dit werkt wel:
case 7 : { byte_1 |= ((0b11111111) & (check_bit == 1));
er komt keurig 00000001 in mijn ext. RAM terecht.
probleem lijkt dan toch in dit stukje te zitten:
(PINC & 0x01)
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Alle code die je laat zien doet dingen die m.i. zou moeten werken met iets als:
byte = PINC;
als je alle bits moet doen, waarom dan per bit overzetten als het in 1x kan?
Of als het per bit echt apart moet:
byte = 0;
for (i=0;i<7;i++)
byte |= PINC & ( 1<<i);
Wat dan precies hetzelfde doet als bovenstaande maar mogelijk heb je nog meer code die dan moet gebeuren in de loop.
Zomaar een stuk code dumpen en zeggen: "ik krijg het niet aan het werk" betekent dat we om te helpen jou code moeten gaan zitten lezen en dan daaruit zien te halen, niet wat het DOET, maar wat het HAD MOETEN DOEN en dan omschrijven naar iets wat wel werkt.
Als je nou eens begint met een voor-mensen-leesbaare omschrijving van het probleem.
het is niet zomaar een stuk code, de volledige code staat hier een stukje boven in dezelfde topic. maar 98 % daarvan werkt goed op 1 stukje na.
dat ene stukje is dus die regel (wat ik heb gepost) die niet werkt, daar zit het probleem.
ik heb het probleem terug gebracht naar dat ene stukje. als dat werkt is het klaar.
ik zal straks (moet nu weg) nog eens beschrijven wat de bedoeling v/d code is, maar dan komen er allemaal suggesties over hoe het ook kan, terwijl het al werkt. en dwalen we af.....ben ik bang.
al word alle hulp door mij enorm gewardeerd 
(PINC & 0x01)
Dit leest de status van alle pinnen van PORTC en doet vervolgens een bitwise and met 0b00000001. Het resultaat is 1 (0b00000001) als de pin PC0 hoog is. En anders is het resultaat 0 (0b00000000).
Niks mis mee dus.
(PORTC & 0x01)
Hier gebeurt hetzelfde, alleen dan niet met de status van de pinnen, maar met de waarde in het PORTC register. Dat is de waarde die je daar zelf in hebt geschreven, en hoeft niet overeen te komen met de status van de pinnen. Als de pinnen op 'ingang' staan (DDRC=0), dan kun je zo testen of de pullup weerstand van PC0 aan staat.
(check_bit == 1)
Hier vergelijk je de waarde van check_bit met 1. Als check_bit de waarde 0b00000001 heeft dan krijg je true, en anders false. Alle 8 bits moeten juist zijn. Als check_bit bijv 0b01000001 heeft dan krijg je ook false. De compiler garandeert dat false gelijk is aan 0, maar true kan in principe van alles zijn. Hier krijg je een 1 terug voor true, maar ik zou daar nooit zo op rekenen.
(PINC & 0b00000001)
Doet een AND operatie tussen overeenkomstige bits van beide kanten.
Het resultaat is 0b0000001 of 0b00000000, afhankelijk van PINC.0 Omdat in de tweede operand alle andere bits op 0 staan worden die in het resultaat ook 0.
(PINC && 0b00000001)
Met een dubbele & wordt er ook een AND operatie uitgevoerd, maar dan worden beide operands eerst als geheel omgezet naar true of false. Het resultaat is ook true of false, true als eender welk bit in PINC hoog is, want dan wordt PINC als geheel ook true, en de andere operand (0b00000001)is ook altijd true.
nog ees de code waar het fout gaat:
case 7 : { byte_1 |= ((PINC & 0x01) & (check_bit == 1));
als ik het een beetje goed begrijp, dan is het stukje:
(PINC & 0x01)
goed.
alleen het stukje:
(check_bit == 1)
is waarschijnlijk fout. ik ken aan check_bit de waarde 1 toe door middel van:
check_bit = 1;
maar dit hoeft natuurlijk niet gelijk aan 0b00000001 te zijn.
en in b.v. case 5 : moet check_bit 0b00000100 zijn.
dus dit moet ik waarschijnlijk anders doen.
omdat ik zoals eerder vermeld de code had gecopieerd v/d IR zender (TSAL) en deze had aangepast voor de TSOP-en, zaten er wat onnodige dingen in, die wel werkte, maar onder het motto simpel is beter heb ik die eruit gesloopt (o.a. de 38kHz "draag golf" voor de IR-led's). ook wat dingen eruit gesloopt die eigenlijk voor weergave op de logic-analyzer waren bedoeld, zodat er een code overblijft die alleen het noodzakelijk bevat.
verder heb ik het advies van henri62 overgenomen, dus niet 2 mS lang kijken naar de input pin v/d TSOP, maar in de ISR direkt naar de input pin kijken.
die ISR ga ik 1,5 mS later in om te zorgen dat ik in het midden v/d TSAL puls zit.
ik zou trouwens nog in gewoon mensen taal uitleggen wat nou precies de bedoeling van de code is. deze code is enkel en alleen voor de IR ontvangers (TSOP).
bedoeling code:
- er zitten 24x een TSOP op een atmega32 verdeeld over 3 poorten A B en C.
- na een comando v/d hoofd controller "TSOP start your scan" gaan die 24x input pinnen v/d TSOP-en 1 voor 1 worden afgevraagd ("1" of "0")
- de statussen v/d input pinnen worden in de atmega 32 opgeslagen.
- later, als de hoofd controller daarom vraagt word de data v/d atmega 32 naar de hoofd controller gestuurd.
thats it........niet meer en niet minder.
alles werkt, op een ding na
en ik zie het voor als nog gewoon niet.
case 6 : { byte_1 |= (PINC & 0x02); break; }
hier is het de bedoeling dat de status van PINC1 in byte_1 word gezet zonder de overige bits te veranderen.
dekees heeft al gezegd dat dat ook het geval is,.....maar iets gaat er fout. (kan ook gewoon aan mij liggen).
om mijn eigen te overtuigen dat de rest wel werkt, verander ik het in:
case 6 : { byte_1 = 0b11001100; break; }
en dan zie ik keurig dat bit patroon (11001100), op mijn display (die zit op de hoofd controller).
om niet afhankelijk te zijn v/h infrarood licht v/d IR led's, heb ik de TSOP-en (8x om te testen op POORTC) hardware matig aan +5 en 0V gesoldeerd met het patroon 0b00111100. maar dat krijg ik dus niet op mijn display.
voor de volledigheid post ik nog eens mijn aan gepaste code.
ik hoop dat iemand ziet wat er fout gaat, mijn dank zal groot zijn 
//*** 4-8-2020 (2) ******************************************************************************************
// TESTING THE RS485 UART TSOP ***************************************************************************
// fuse: ext. crystal/resonater medium freq. start up 16 64
// fuse: J-tag uitvinken
#define F_CPU 8000000UL // 8 MHz clock speed
#include <stdio.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
int check_bit = 0;
int receivedbyte = 0;
int bytetosend = 0;
int column_counter_byte_1 = 0;
int column_counter_byte_2 = 0;
int column_counter_byte_3 = 0;
int byte_1 = 0;
int byte_2 = 0;
int byte_3 = 0;
uint8_t BitCounter = 0;
volatile start_scan = 0;
int start_send_data_byte_1 = 0;
int start_send_data_byte_2 = 0;
int start_send_data_byte_3 = 0;
int shift_byte_out = 0;
uint8_t columns_byte_1 [300];
uint8_t columns_byte_2 [300];
uint8_t columns_byte_3 [300];
ISR(TIMER1_COMPA_vect)
{
static uint8_t BitCounter = 0;
switch(BitCounter++)
{
case 0 : { byte_1 |= (PINC & 0x80); PORTD |= (1 << PIND3); break; }
case 1 : { byte_1 |= (PINC & 0x40); break; }
case 2 : { byte_1 |= (PINC & 0x20); break; }
case 3 : { byte_1 |= (PINC & 0x10); break; }
case 4 : { byte_1 |= (PINC & 0x08); break; }
case 5 : { byte_1 |= (PINC & 0x04); break; }
case 6 : { byte_1 |= (PINC & 0x02); break; }
case 7 : { byte_1 |= (PINC & 0x01);
if(column_counter_byte_1 < sizeof(columns_byte_1) )
{
columns_byte_1 [column_counter_byte_1] = byte_1;
column_counter_byte_1 += 1;
}
break;
}
case 8 : { byte_2 |= (PINA & 0x80); PORTD |= (1 << PIND4); PORTD &= ~(1 << PIND3); break; }
case 9 : { byte_2 |= (PINA & 0x40); break; }
case 10: { byte_2 |= (PINA & 0x20); break; }
case 11: { byte_2 |= (PINA & 0x10); break; }
case 12: { byte_2 |= (PINA & 0x08); break; }
case 13: { byte_2 |= (PINA & 0x04); break; }
case 14: { byte_2 |= (PINA & 0x02); break; }
case 15: { byte_2 |= (PINA & 0x01);
if(column_counter_byte_2 < sizeof(columns_byte_2) )
{
columns_byte_2 [column_counter_byte_2] = byte_2;
column_counter_byte_2 += 1;
}
break;
}
case 16: { byte_3 |= (PINB & 0x80); PORTD |= (1 << PIND7); PORTD &= ~(1 << PIND4); break; }
case 17: { byte_3 |= (PINB & 0x40); break; }
case 18: { byte_3 |= (PINB & 0x20); break; }
case 19: { byte_3 |= (PINB & 0x10); break; }
case 20: { byte_3 |= (PINB & 0x08); break; }
case 21: { byte_3 |= (PINB & 0x04); break; }
case 22: { byte_3 |= (PINB & 0x02); break; }
case 23: { byte_3 |= (PINB & 0x01);
if(column_counter_byte_3 < sizeof(columns_byte_3) )
{
columns_byte_3 [column_counter_byte_3] = byte_3;
column_counter_byte_3 += 1;
}
break;
}
case 24:
{
PORTD &= ~(1 << PIND7);
BitCounter = 0;
start_scan = 0;
break;
}
} // from: switch
} // from: ISR
ISR(TIMER1_COMPB_vect)
{
PORTB = 0;
PORTA = 0;
PORTC = 0;
}
int main(void)
{
DDRA = 0b00000000;
PORTA = 0b11111111;
DDRB = 0b00000000;
PORTB = 0b11111111;
DDRC = 0b00000000;
PORTC = 0b11111111;
DDRD = 0b11111110; // PD0 = RXD
// PORTD = 0b00000001;
sei();
TCCR1B |= (1 << WGM12); // CTC-mode,
TIMSK |= (1 << OCIE1A) | (1 << OCIE1B) ; // timer1 A & B compare match interrupt enabled
OCR1A = 32000; // 4mS
OCR1B = 100;
UCSRA = (1 << MPCM); // enable: multi processor communication mode
UCSRB = (1 << RXEN) | (1 << TXEN)| (1 << UCSZ2); // Turn on the transmission and reception circuit
UCSRC = (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // 9-bit mode, URSEL bit for selecting UCSRC
UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register
UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
for(;;)
{
while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been received and is ready to be read from UDR
receivedbyte = UDR; // Fetch the received byte value into the variable "ReceivedByte"
//*** adress numbering: TSAL 1-20 and TSOP 21-40 *******************************************************
if (receivedbyte == 21) // adress byte
{
UCSRA &=~(1 << MPCM); // make MPCM "0"
while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been received and is ready to be read from UDR
receivedbyte = UDR; // Fetch the received byte value into the variable "ReceivedByte"
if (receivedbyte == 0b11110000) // is the data byte: start your scan
{
_delay_ms(3); // to make we look 1 mS after the TSAL puls is started
start_scan = 1;
column_counter_byte_1 = 0; // 0, so that the first saved byte comes on 0 in the array
column_counter_byte_2 = 0;
column_counter_byte_3 = 0;
}
if (receivedbyte == 0b00000001) // is the data byte: send the data 1e byte to the master
{
_delay_ms(5);
start_send_data_byte_1 = 1;
}
if (receivedbyte == 0b00000010) // is the data byte: send the data 2e byte to the master
{
_delay_ms(5);
start_send_data_byte_2 = 1;
}
if (receivedbyte == 0b00000011) // is the data byte: send the data 3e byte to the master
{
_delay_ms(5);
start_send_data_byte_3 = 1;
}
while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been received and is ready to be read from UDR
receivedbyte = UDR; // Fetch the received byte value into the variable "ReceivedByte"
if (receivedbyte == 0b11111111) // is the stop byte
{
UCSRA = (1 << MPCM); // enable: multi processor communication mode
}
}
//********** TSOP ****************************************************************************************
while (start_scan == 1)
{
TCCR1B |= (1 << CS10); // start timer with prescaler = 0
// PORTA = byte_1; // for testing ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
if (start_scan == 0)
{
TCCR1B &= ~(1 << CS10); // stop timer with prescaler = 0
byte_1 = 0; // waarschijnlijk alleen voor testen^^^^^^^^^^^^^^^^^^
}
while (start_send_data_byte_1 == 1)
{
PORTD |= (1 << PIND3); // for checking rood = "1" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PORTD |= (1 << PIND2); // switch MAX485 as transmitter pin 2 & 3 = "1"
for (shift_byte_out = 0; shift_byte_out < 302; shift_byte_out ++) //test ^^^^^^^^^^^^^^
{
while ((UCSRA & (1 << UDRE)) == 0) {}; // do nothing till the UDR is ready to receive
bytetosend = columns_byte_1[shift_byte_out]; // TEST array ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UDR = bytetosend;
}
start_send_data_byte_1 = 0;
PORTD &= ~(1 << PIND3); // for checking rood = "0" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
while (start_send_data_byte_2 == 1)
{
PORTD |= (1 << PIND4); // // for checking geel = "1" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PORTD |= (1 << PIND2); // switch MAX485 as transmitter pin 2 & 3 = "1"
for (shift_byte_out = 0; shift_byte_out < 302; shift_byte_out ++)
{
while ((UCSRA & (1 << UDRE)) == 0) {}; // do nothing till the UDR is ready to receive
bytetosend = columns_byte_2[shift_byte_out]; // TEST array ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UDR = bytetosend;
}
start_send_data_byte_2 = 0;
PORTD &= ~(1 << PIND4); // for checking geel = "0" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
while (start_send_data_byte_3 == 1)
{
PORTD |= (1 << PIND7); // for checking groen = "1" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PORTD |= (1 << PIND2); // switch MAX485 as transmitter pin 2 & 3 = "1"
for (shift_byte_out = 0; shift_byte_out < 302; shift_byte_out ++)
{
while ((UCSRA & (1 << UDRE)) == 0) {}; // do nothing till the UDR is ready to receive
bytetosend = columns_byte_3[shift_byte_out]; // TEST array ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UDR = bytetosend;
}
start_send_data_byte_3 = 0;
PORTD &= ~(1 << PIND7); // for checking groen = "0" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
if (start_send_data_byte_3 == 0)
{
PORTD &= ~(1 << PIND2); // switch MAX485 as receiver pin 2 & 3 = "0"
}
} // from: for (;;)
} // from: main
[Bericht gewijzigd door trix op (100%)]
case 6 : { byte_1 |= (PINC & 0x02); break; }
Je doet hier een OR operatie zodat bit 2 in byte_1 gezet wordt als PINC.2 hoog is.
Maar ik zie nergens dat er ook bits worden gereset. Je begint wel met byte_1 = 0, maar vervolgens kunnen de bits alleen nog maar omhoog. Iemand zal die toch voor elke scan moeten resetten.
En dat geldt ook voor byte_2 en byte_3 denk ik.
ik test nu met 1 scan (dus niet elke = meerdere).
ik geef het programma maar 1x een start (0b11110000) en dat vult de array dus met maar 1 byte.
dus ik vermoed dat wat je suggereert toch niet DE oplossing is.
bovendien gaat mijn vaste test bit patroon 0b11001100 wel zonder problemen.
neemt niet weg dat er nog gereset moet worden. tnx.
tussendstand:
het werkt,......de interne pull-up op PORTC (allemaal TSOP-en) was de boosdoener
. deze dus uitgeschakeld.
nu nog een start timings probleempje.
straks als alles werkt zal ik nog eens de werkende code plaatsen voor de volledigheid. want ik heb er naar aanleiding van dekees & henri62 ook nog wat in veranderd.
bedankt zover 
edit:
timings probleempje opgelosd, en de code nog wat opgeschoond:
op naar het volgend probleem
.
//*** 5-8-2020 *******************************************************************************************
// TESTING THE RS485 UART TSOP ***************************************************************************
// fuse: ext. crystal/resonater medium freq. start up 16 64
// fuse: J-tag uitvinken
#define F_CPU 8000000UL // 8 MHz clock speed
#include <stdio.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
int receivedbyte = 0;
int bytetosend = 0;
int column_counter_byte_1 = 0;
int column_counter_byte_2 = 0;
int column_counter_byte_3 = 0;
int byte_1 = 0;
int byte_2 = 0;
int byte_3 = 0;
uint8_t BitCounter = 0;
volatile start_scan = 0;
int start_send_data_byte_1 = 0;
int start_send_data_byte_2 = 0;
int start_send_data_byte_3 = 0;
int shift_byte_out = 0;
uint8_t columns_byte_1 [300];
uint8_t columns_byte_2 [300];
uint8_t columns_byte_3 [300];
ISR(TIMER1_COMPA_vect)
{
static uint8_t BitCounter = 0;
switch(BitCounter++)
{
case 0 : { byte_1 |= (PINC & 0x80); PORTD |= (1 << PIND3); break; }
case 1 : { byte_1 |= (PINC & 0x40); break; }
case 2 : { byte_1 |= (PINC & 0x20); break; }
case 3 : { byte_1 |= (PINC & 0x10); break; }
case 4 : { byte_1 |= (PINC & 0x08); break; }
case 5 : { byte_1 |= (PINC & 0x04); break; }
case 6 : { byte_1 |= (PINC & 0x02); break; }
case 7 : { byte_1 |= (PINC & 0x01);
if(column_counter_byte_1 < sizeof(columns_byte_1) )
{
columns_byte_1 [column_counter_byte_1] = byte_1;
column_counter_byte_1 += 1;
}
break;
}
case 8 : { byte_2 |= (PINA & 0x80); PORTD |= (1 << PIND4); PORTD &= ~(1 << PIND3); break; }
case 9 : { byte_2 |= (PINA & 0x40); break; }
case 10: { byte_2 |= (PINA & 0x20); break; }
case 11: { byte_2 |= (PINA & 0x10); break; }
case 12: { byte_2 |= (PINA & 0x08); break; }
case 13: { byte_2 |= (PINA & 0x04); break; }
case 14: { byte_2 |= (PINA & 0x02); break; }
case 15: { byte_2 |= (PINA & 0x01);
if(column_counter_byte_2 < sizeof(columns_byte_2) )
{
columns_byte_2 [column_counter_byte_2] = byte_2;
column_counter_byte_2 += 1;
}
break;
}
case 16: { byte_3 |= (PINB & 0x80); PORTD |= (1 << PIND7); PORTD &= ~(1 << PIND4); break; }
case 17: { byte_3 |= (PINB & 0x40); break; }
case 18: { byte_3 |= (PINB & 0x20); break; }
case 19: { byte_3 |= (PINB & 0x10); break; }
case 20: { byte_3 |= (PINB & 0x08); break; }
case 21: { byte_3 |= (PINB & 0x04); break; }
case 22: { byte_3 |= (PINB & 0x02); break; }
case 23: { byte_3 |= (PINB & 0x01);
if(column_counter_byte_3 < sizeof(columns_byte_3) )
{
columns_byte_3 [column_counter_byte_3] = byte_3;
column_counter_byte_3 += 1;
}
break;
}
case 24:
{
PORTD &= ~(1 << PIND7);
BitCounter = 0;
start_scan = 0;
byte_1 = 0;
byte_2 = 0;
byte_3 = 0;
break;
}
} // from: switch
} // from: ISR
int main(void)
{
DDRA = 0b00000000;
PORTA = 0b11111111;
DDRB = 0b00000000;
PORTB = 0b11111111;
DDRC = 0b00000000;
// PORTC = 0b11111111; // have to be out for the correct working
DDRD = 0b11111110; // PD0 = RXD
// PORTD = 0b00000001;
sei();
TCCR1B |= (1 << WGM12); // CTC-mode,
TIMSK |= (1 << OCIE1A); // timer1 A compare match interrupt enabled
OCR1A = 32000; // 4mS
UCSRA = (1 << MPCM); // enable: multi processor communication mode
UCSRB = (1 << RXEN) | (1 << TXEN)| (1 << UCSZ2); // Turn on the transmission and reception circuit
UCSRC = (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // 9-bit mode, URSEL bit for selecting UCSRC
UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register
UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
for(;;)
{
while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been received and is ready to be read from UDR
receivedbyte = UDR; // Fetch the received byte value into the variable "ReceivedByte"
//*** adress numbering: TSAL 1-20 and TSOP 21-40 *******************************************************
if (receivedbyte == 21) // adress byte
{
UCSRA &=~(1 << MPCM); // make MPCM "0"
while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been received and is ready to be read from UDR
receivedbyte = UDR; // Fetch the received byte value into the variable "ReceivedByte"
if (receivedbyte == 0b11110000) // is the data byte: start your scan
{
start_scan = 1;
column_counter_byte_1 = 0; // 0, so that the first saved byte comes on 0 in the array
column_counter_byte_2 = 0;
column_counter_byte_3 = 0;
}
if (receivedbyte == 0b00000001) // is the data byte: send the data 1e byte to the master
{
_delay_ms(5);
start_send_data_byte_1 = 1;
}
if (receivedbyte == 0b00000010) // is the data byte: send the data 2e byte to the master
{
_delay_ms(5);
start_send_data_byte_2 = 1;
}
if (receivedbyte == 0b00000011) // is the data byte: send the data 3e byte to the master
{
_delay_ms(5);
start_send_data_byte_3 = 1;
}
while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been received and is ready to be read from UDR
receivedbyte = UDR; // Fetch the received byte value into the variable "ReceivedByte"
if (receivedbyte == 0b11111111) // is the stop byte
{
UCSRA = (1 << MPCM); // enable: multi processor communication mode
}
}
//********** TSOP ****************************************************************************************
while (start_scan == 1)
{
TCCR1B |= (1 << CS10); // start timer with prescaler = 0
// PORTA = byte_1; // for testing ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
if (start_scan == 0)
{
TCCR1B &= ~(1 << CS10); // stop timer with prescaler = 0
byte_1 = 0; // waarschijnlijk alleen voor testen^^^^^^^^^^^^^^^^^^
}
while (start_send_data_byte_1 == 1)
{
PORTD |= (1 << PIND3); // for checking rood = "1" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PORTD |= (1 << PIND2); // switch MAX485 as transmitter pin 2 & 3 = "1"
for (shift_byte_out = 0; shift_byte_out < 302; shift_byte_out ++) //test ^^^^^^^^^^^^^^
{
while ((UCSRA & (1 << UDRE)) == 0) {}; // do nothing till the UDR is ready to receive
bytetosend = columns_byte_1[shift_byte_out]; // TEST array ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UDR = bytetosend;
}
start_send_data_byte_1 = 0;
PORTD &= ~(1 << PIND3); // for checking rood = "0" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
while (start_send_data_byte_2 == 1)
{
PORTD |= (1 << PIND4); // // for checking geel = "1" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PORTD |= (1 << PIND2); // switch MAX485 as transmitter pin 2 & 3 = "1"
for (shift_byte_out = 0; shift_byte_out < 302; shift_byte_out ++)
{
while ((UCSRA & (1 << UDRE)) == 0) {}; // do nothing till the UDR is ready to receive
bytetosend = columns_byte_2[shift_byte_out]; // TEST array ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UDR = bytetosend;
}
start_send_data_byte_2 = 0;
PORTD &= ~(1 << PIND4); // for checking geel = "0" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
while (start_send_data_byte_3 == 1)
{
PORTD |= (1 << PIND7); // for checking groen = "1" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PORTD |= (1 << PIND2); // switch MAX485 as transmitter pin 2 & 3 = "1"
for (shift_byte_out = 0; shift_byte_out < 302; shift_byte_out ++)
{
while ((UCSRA & (1 << UDRE)) == 0) {}; // do nothing till the UDR is ready to receive
bytetosend = columns_byte_3[shift_byte_out]; // TEST array ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UDR = bytetosend;
}
start_send_data_byte_3 = 0;
PORTD &= ~(1 << PIND7); // for checking groen = "0" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
if (start_send_data_byte_3 == 0)
{
PORTD &= ~(1 << PIND2); // switch MAX485 as receiver pin 2 & 3 = "0"
}
} // from: for (;;)
} // from: main