Problem mit mehreren UARTs (Mega <> ATtiny)

Hallo,

ich erleide herbe Rückschläge wegen den UARTs.
Beim Aufbau eines generellen Kommunikationstests traf ich auf Probleme.
Manchmal gings und manchmal nicht, je nach Codekonstellation. Und ich wußte nicht genau warum, der Code scheint i.O.

Momentan stelle ich fest, dass es funktioniert, wenn ich einzeln

Mega-UART1 > ... > ATtiny841-UART1 sende und ATtiny841-UART0 > ... > Mega-UART2 sende und an UART0 im Terminal anzeigen lasse.

oder

Mega-UART2 > ... > ATtiny841-UART0 sende und ATtiny841-UART1 > ... > Mega-UART1 sende und an UART0 im Terminal anzeigen lasse.

lasse ich beides im Sekundentakt abwechselnd ablaufen, kommt teilweise verstümmelter Code.
Das seltsame dabei ist, die zugehörige Antwort kommt genau eine Sekunde später und nicht sofort.
Ich weiß nicht warum. Irgendwas kommt sich ins Gehege zwischen den UARTs.

Mache ich das Paket komplett, dann sendet zwar der Mega fleißig, aber der ATtiny sendet nichts mehr zurück.
Ich sehe das auch mittels Logik Analyzer und serial Decoder.

Ich bin ratlos. Es muss doch möglich sein, wechselweise auf beiden Mega UARTs etwas zusenden und im Gegenüber
auf jeweils der anderen UART wieder auszugeben und im Mega dann auch auf der jeweils anderen UART einzulesen und anzeigen.
Die Nachricht sollte doch ohne nennenswerte Verzögerung die Runde machen.

Wenn ich alles einzeln teste funktioniert der Befehlsvergleich im ATtiny und die passende Antwort kommt umgehend, sehe ich im L.A.

/* Arduino Mega2560 */
const byte SERIAL_BUFFER_SIZE = 20;      
char serialBuffer_1[SERIAL_BUFFER_SIZE];
char serialBuffer_2[SERIAL_BUFFER_SIZE];

unsigned long last_millis;
bool toggle = true;

void setup()  { 
  Serial.begin(250000);
  Serial1.begin(250000);
  Serial2.begin(250000);
}

  
void loop() {  

  handle_Serial_2_to_Serial_0();

  handle_Serial_1_to_Serial_0();

  
  if (millis() - last_millis > 1000) {
    last_millis = millis();

    if (toggle == true) {
      Serial1.println("REQUEST"); 
    }
    if (toggle == false) {  
      Serial2.println("GOOD"); 
    }
    toggle = !toggle;
  }  
  
} // loop Ende


// ****** Funktionen ******* //
bool read_Serial_1()
{
  static byte index;

  if (Serial1.available() > 0)  {   
    char c = Serial1.read();
    if (c >= 32 && (index < SERIAL_BUFFER_SIZE - 1))
      {
        serialBuffer_1[index++] = c;
      }
      else if ( (c == '\r' || c == '\n') && index > 0) {
        serialBuffer_1[index] = '\0';
        index = 0;
        return true;
      } 
  }
  return false;
}


bool read_Serial_2()
{
  static byte index;

  if (Serial2.available() > 0)  {   
    char c = Serial2.read();
    if (c >= 32 && (index < SERIAL_BUFFER_SIZE - 1))
      {
        serialBuffer_2[index++] = c;
      }
      else if ( (c == '\r' || c == '\n') && index > 0) {
        serialBuffer_2[index] = '\0';
        index = 0;
        return true;
      } 
  }
  return false;
}


void handle_Serial_1_to_Serial_0 ()
{
  if( read_Serial_1() == true)  { 
    Serial.println(serialBuffer_1); 
    memset(serialBuffer_1,'\0',sizeof(serialBuffer_1));  // seriellen Buffer löschen
  }
}


void handle_Serial_2_to_Serial_0 ()
{
  if( read_Serial_2() == true)  { 
    Serial.println(serialBuffer_2); 
    memset(serialBuffer_2,'\0',sizeof(serialBuffer_2));  // seriellen Buffer löschen
  }
}
/* ATtiny841 */ 

#define F_CPU 8000000UL  // Systemtakt in Hz

#include <avr/io.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <util/atomic.h>    // für cli() und sei() mit SREG Sicherung

/* 
  UART Berechnungen des Wertes für das Baudratenregister aus Taktrate und gewünschter Baudrate
*/
#define BAUD 250000UL    // gewünschte Baudrate
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // sauber runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)		// Fehler in Promille, 1000 = kein Fehler.
#if ((BAUD_ERROR<995) || (BAUD_ERROR>1005))
  #error Systematischer Fehler der Baudrate greosser 0,5% und damit zu hoch! 
#endif

volatile uint32_t millis_count;		// ISR Timer 0 Variable
volatile uint32_t second_count;		// ISR Timer 0 Variable
uint32_t last_millis;
uint32_t last_second;

const uint8_t SERIAL_BUFFER_SIZE = 20;
char Buffer_Serial_0[SERIAL_BUFFER_SIZE];
char Buffer_Serial_1[SERIAL_BUFFER_SIZE];

/* *** Funktion Deklarationen *** */
/* *** UART 0 *** */
void UART0_Init();					// Pin 8,9, TxD1/RxD1
void UART0_sendChar(unsigned char data);
void UART0_sendString (const char *s);
void UART0_send_uint32(uint32_t zahl);
unsigned char UART0_empfangen();
/* *** UART 1 *** */
void UART1_Init();					// Pin 8,9, TxD1/RxD1
void UART1_sendChar(unsigned char data);
void UART1_sendString (const char *s);
void UART1_send_uint32(uint32_t zahl);
unsigned char UART1_empfangen();
/* *** UARTs read and send *** */
bool read_Serial_0();
bool read_Serial_1();
void handle_Serial_0_to_Serial_1();
void handle_Serial_1_to_Serial_0();

uint32_t millis();
uint32_t second();
ISR(TIMER0_COMPA_vect);
void set_Timer0();					// Timer 0, millis, seconds	


int main(void)
{  
	// µC Takt langsam justieren zum testen
	
	OSCCAL0 = 40;	_delay_ms(100);
	OSCCAL0 = 39;	_delay_ms(100);
	OSCCAL0 = 38;	_delay_ms(100);
	OSCCAL0 = 37;	_delay_ms(100);
				
	UART0_Init();
	UART1_Init();
	set_Timer0();	// millis, seconds
    										
    while (1) 
    {   	
		handle_Serial_0_to_Serial_1();
		
		handle_Serial_1_to_Serial_0();	
	}
}


/* *** Funktionen *** */

void UART0_Init()
{
	UBRR0H = UBRR_VAL >> 8;				// Set baud rate
	UBRR0L = UBRR_VAL & 0xFF;
	UCSR0B = (1<<RXEN0)|(1<<TXEN0);		// Enable receiver and transmitter
	UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);	// Set frame format: 8data, 1stop bit
}


void UART1_Init()
{
	UBRR1H = UBRR_VAL >> 8;				// Set baud rate
	UBRR1L = UBRR_VAL & 0xFF;
	UCSR1B = (1<<RXEN1)|(1<<TXEN1);		// Enable receiver and transmitter
	UCSR1C = (1<<UCSZ11)|(1<<UCSZ10);	// Set frame format: 8data, 1stop bit
}


void UART0_sendChar( unsigned char data )
{
	while ( !( UCSR0A & (1<<UDRE0)) )	// wait for empty transmit buffer
	;
	UDR0 = data;	// Put data into buffer, sends the data
}


void UART1_sendChar( unsigned char data )
{
	while ( !( UCSR1A & (1<<UDRE1)) )	// wait for empty transmit buffer
	;
	UDR1 = data;	// Put data into buffer, sends the data
}


void UART0_sendString (const char *string)
{									// Vergleich auf ASCII Zeichen '\0' (NUL)
	while (*string != 0x00) {		// "String-Endezeichen" (Null-Terminator)
		UART0_sendChar(*string);	// vorderstes Zeichen senden
		string++;
	}
}


void UART1_sendString (const char *string)
{									// Vergleich auf ASCII Zeichen '\0' (NUL)
	while (*string != 0x00) {		// "String-Endezeichen" (Null-Terminator)
		UART1_sendChar(*string);	// vorderstes Zeichen senden
		string++;
	}
}


void UART0_send_uint32(uint32_t zahl)
{	// convert eine long Zahl zu einem String
	char string[11];
	ultoa(zahl, string, 10);	// convert unsigned long to string, radix=10
	UART0_sendString(string);
}


void UART1_send_uint32(uint32_t zahl)
{	// convert eine long Zahl zu einem String
	char string[11];
	ultoa(zahl, string, 10);	// convert unsigned long to string, radix=10
	UART1_sendString(string);
}


unsigned char UART0_empfangen()
{
	while ( !(UCSR0A & (1<<RXC0)) )	// Wait for data to be received
	;
	return UDR0;		// Get and return received data from buffer
}


unsigned char UART1_empfangen()
{
	while ( !(UCSR1A & (1<<RXC1)) )	// Wait for data to be received
	;
	return UDR1;		// Get and return received data from buffer
}


void set_Timer0 ()		// millis, seconds
{
	cli();									// Interupts ausschalten
	TCNT0 = 0;								// Register Reset
	TCCR0A = 0;
	TCCR0B = 0;
	TIMSK0 = 0;
	TCCR0A = (1 << WGM01);					// CTC Modus
	OCR0A = 124;							// TOP, (F_CPU/PRESCALER)/1000-1
	TIMSK0 |= (1 << OCIE0A);				// Interupts einschalten
	TCCR0B |= (1 << CS01) | (1 << CS00);	// Prescaler 64, Timer starten
	sei();
}


bool read_Serial_0()
{
	static uint8_t index;

	char c = UART0_empfangen();
	if (c >= 32 && (index < SERIAL_BUFFER_SIZE - 1))
	{
		Buffer_Serial_0[index++] = c;
	}
	else if ( (c == '\r' || c == '\n') && index > 0) {
		Buffer_Serial_0[index] = '\0';
		index = 0;
		return true;
	}
	return false;
}


bool read_Serial_1()
{
	static uint8_t index;

	char c = UART1_empfangen();
	if (c >= 32 && (index < SERIAL_BUFFER_SIZE - 1))
	{
		Buffer_Serial_1[index++] = c;
	}
	else if ( (c == '\r' || c == '\n') && index > 0) {
		Buffer_Serial_1[index] = '\0';
		index = 0;
		return true;
	}
	return false;
}


void handle_Serial_0_to_Serial_1 ()
{
	if( read_Serial_0() == true)  {
		
		if (strncmp(Buffer_Serial_0, "REQUEST", 7) == 0)  {
			UART1_sendString("REQUEST UART_0-1");	UART1_sendChar('\n');
			UART1_send_uint32( millis() );			UART1_sendChar('\n');
		}
		else if (strncmp(Buffer_Serial_0, "GOOD", 4) == 0)  {
			UART1_sendString("GOOD UART_0-1");		UART1_sendChar('\n');
			UART1_send_uint32( millis() );			UART1_sendChar('\n');
		}
		else {
			UART1_sendString("BACK UART1");			UART1_sendChar('\n');
			UART1_sendString(Buffer_Serial_0);		UART1_sendChar('\n');
			UART1_send_uint32( millis() );			UART1_sendChar('\n');
		}
		memset(Buffer_Serial_0,'\0',sizeof(Buffer_Serial_0));  // seriellen Buffer löschen
	}
}


void handle_Serial_1_to_Serial_0 ()
{
	if( read_Serial_1() == true)  {
		
		if (strncmp(Buffer_Serial_1, "REQUEST", 7) == 0)  {
			UART0_sendString("REQUEST UART_1-0");	UART0_sendChar('\n');
			UART0_send_uint32( second() );			UART0_sendChar('\n');
		}
		else if (strncmp(Buffer_Serial_1, "GOOD", 4) == 0)  {
			UART0_sendString("GOOD UART_1-0");		UART0_sendChar('\n');
			UART0_send_uint32( second() );			UART0_sendChar('\n');
		}
		else {
			UART0_sendString("BACK UART0");			UART0_sendChar('\n');
			UART0_sendString(Buffer_Serial_1);		UART0_sendChar('\n');
			UART0_send_uint32( second() );			UART0_sendChar('\n');
		}
		memset(Buffer_Serial_1,'\0',sizeof(Buffer_Serial_1));  // seriellen Buffer löschen
	}
}


uint32_t millis()
{
	uint32_t value = 0;
	ATOMIC_BLOCK (ATOMIC_RESTORESTATE)
	{
		value = millis_count;
	}
	return value;
}


uint32_t second()
{
	uint32_t value = 0;
	ATOMIC_BLOCK (ATOMIC_RESTORESTATE)
	{
		value = second_count;
	}
	return value;
}


ISR(TIMER0_COMPA_vect)
{
	static uint32_t local_millis = 0;
	
	millis_count++;				// Zähler für Millisekunden
	local_millis++;

	if (local_millis > 999) {
		second_count++;			// Zähler für Sekunden
		local_millis = 0;
	}
}

Mega UART1 ist über kreuz mit ATtiny UART1 verbunden.
Mega UART2 ist über kreuz mit ATtiny UART0 verbunden.

Hallo,

noch zwei Bilder vom Mitschnitt.
im ersten zoom in, da sieht man das vom "REQUEST" etwas fehlt. Genau wie im Terminal sichtbar.

Im anderen sieht man die Verzögerung.
Gesendet wird auf dem 2. und 4. Kanal vom Mega aus gesehen.
Deshalb müsste auf dem 3. Kanal umgehend eine Antwort kommen wenn auf dem 2. was gesendet wurde.
Genauso wenn auf dem 4. gesendet wird müßte auf dem 1. umgehen die umgeleitete Antwort kommen.
Sieht alles seltsam aus zeitlich gesehen.

hi,

genau eine sekunde ist schon seltsam, das ist das standard-timeout bei vielen funktionen der serial-library. sehe zwar jetzt keine in Deinem sketch, aber setz' es doch mal in beiden sketches am anfang für alle benutzten schnittstellen mit settimeout auf 500,
ob sich was ändert...

gruß stefan

Hallo,

du meinst das hier https://www.arduino.cc/en/Serial/setTimeout
war ein Versuch wert, bringt leider keine Abhilfe.
Die zeitliche Verzögerung der Übertragung geht genau mit der eingestellten millis "toggle" Zeit mit.
Was eigentlich nicht sein darf, weil ja ohne Wartezeit jederzeit gelesen werden kann in loop.
Habs nochmal versucht besser darzustellen.

Wenn ich im Mega Sketch eine serielle in toggle auskommentiere, egal welche, dann geht nichts mehr, es kommt nichts zurück.

Irgendwie muss ein Bufferüberlauf stattfinden oder ein Abschluss kommt nicht an oder sowas, habe ich das Gefühl.
Weiß nur nicht wo ich ansetzen soll. Habe den Code schon tausendmal durchgeschaut.

Hallo,

wenn ich es wieder einzeln teste, zum Bsp. der Mega sendet nur auf Uart1 und der ATtiny liest nur von Uart1 und sendet damit nur auf Uart0 zurück (kommt im Mega auf Uart2 an), dann klappt alles. Die Antwort erfolgt umgehend sobald das Endezeichen '\r' erkannt wird. Genauso wie ich mir das vorstelle.

Meine Vermutung liegt nachwievor das sich die Buffer gegenseitig ins Gehege kommen. Nur wo und warum das weiß ich nicht.

Meine Vermutung liegt nachwievor das sich die Buffer gegenseitig ins Gehege kommen. Nur wo und warum das weiß ich nicht.

Ich habe mir das mal angesehen.....

Der Mega Code scheint ja zu funktionieren.
Genau habe ich ihn nicht untersucht.....

Beim Tiny Code habe ich ein Problem gefunden.

Deine "Empfangen" Routinen sind blockierend.
Wenn also auf USART0 empfangen werden soll, aber nix kommt, dann geht alles auf USART1 verloren.
Bis auf 1 Byte.

Andersrum natürlich genau so.

Und auch beim senden, wird jeglicher Empfang blockiert.

Kann es das schon sein, was dir einen Streich spielt?


Auch das Timing scheint mir eng zu sein...
Innerhalb von 40µs muss ein Zeichen aus der USART abgeholt worden sein, sonst gehen Bytes/Zeichen verlustig.

Hallo,

Danke das du dir die Zeit nimmst.

Der Code ist aus den Datenblatt Beispielen. Ich hatte das so verstanden das die whiles immer nur unbedeutend kurz blockieren bis die Übertragungs selbst fertig ist. Wenn nichts da ist, wird es übersprungen.
Du meinst, sobald zum Bsp. UART0_empfangen() aufgerufen wird blockiert der gesamte Code bis wirklich irgendwas reinkommt?

Beim senden UART0_sendChar bin ich mir allerdings sicher das er nicht blockiert. Die while soll doch warten und prüfen ob der UART Buffer leer ist vor Neubefüllung. Da er ja meistens leer sein sollte, dürfte die while doch im Grunde genommen nicht wirklich blockieren.

Was du mit den 40µs meinst verstehe ich nicht. Was muss von wem innerhalb 40µs abgeholt werden?
Die Daten liegen doch solange im Buffer bis sie jemand abholt und bleiben solange unverfälscht bis sie von neuen reinkommenden Daten überschrieben werden. So hatte ich das jedenfalls verstanden.

Allerdings, wenn der Empfang den gesamten ATtiny Code blockiert,dann kann auch kein Buffer abgeholt werden und dann kommt schon der nächste Datenstrom rein. Das könnte die Verstümmelung erklären.

Also heißt das ich muss auf Interrupt Steuerung umbauen und darf keine Flags auswerten?

Beim senden UART0_sendChar bin ich mir allerdings sicher das er nicht blockiert.

Doch, tut es.
Zumindest bis zu 40µs.
So lange, bis das vorherige Zeichen im Schieberegister gelandet ist.
(zu den 40µs gleich mehr)

Aber du verwendest ja gar nicht: UART0_sendChar()
Sondern: UART0_sendString().
Und das blockiert bis der ganze String draußen ist(-2 Zeichen).
Bei 10 zu sendenden Zeichen, können auf den beiden seriellen Eingängen zusammen 14 Byte ins Nirvana wandern.
Auch, wenn es bei deiner Anwendung nicht ins Gewicht fällt, solltest du das doch im Hinterkopf behalten.
Denke ich mal....

Du meinst, sobald zum Bsp. UART0_empfangen() aufgerufen wird blockiert der gesamte Code bis wirklich irgendwas reinkommt?

So sehe ich das in deinem Code.

Was du mit den 40µs meinst verstehe ich nicht.

1 Byte wird zu 10Bit (8Daten+1start+1stopp)
Bei 250000Baud macht das also 25000Byte Pro Sekunde

1/25000 = 0.00004
40µs Pro Byte

Was muss von wem innerhalb 40µs abgeholt werden?

Für das "Wem" bist du verantwortlich.

Das "Was":
Da ein Byte selten alleine kommt, muss das jeweils fertig angekommene innerhalb von 40µs abgeholt werden, sonst verschwinden Daten im Nirvana.

Die Daten liegen doch solange im Buffer bis sie jemand abholt und bleiben solange unverfälscht bis sie von neuen reinkommenden Daten überschrieben werden. So hatte ich das jedenfalls verstanden.

Welcher Buffer?
Der USART Buffer?
Da passt 1 Byte rein.
Darum musst du ja bei 250000Baud schon etwas Gas geben, den rechtzeitig zu leeren.

Also heißt das ich muss auf Interrupt Steuerung umbauen und darf keine Flags auswerten?

Nunja...
Entweder Interrupts, oder ein rasend schnelles Polling, würde ich mal sagen....

Hallo,

jetzt wird mir einiges klarer.
Das mit dem Buffer ist schnell geklärt. Ich hatte auch beim ATtiny fälschlicherweise die 63Byte Ringbuffer im Hinterkopf wie wir sie beim Arduino haben. Deshalb dachte ich man hätte auch hier alle Zeit der Welt. Aber ist ja nur intern unsichtbar zwischengeschoben.

Das mit dem senden und empfangen meine ich nun auch verstanden zu haben, das dort das Problem liegt, wie du erkannt hast. Weil blockieren darf auch später nichts, auch wenn ich nur eine UART am Ende nutzen werde. Das wäre mir später mörderisch auf die Füße gefallen. Der Code wächst ja noch.

Großes Danke.

Fein!

Hört sich an, als wärst du jetzt auf dem "wahren Pfad".
:o :o :o

Und schön dass ich dir helfen konnte.

Wenn ich recht informiert bin, wird HardwareSerial auf einem Uno jeweils per Interrupt geweckt, wenn der UART sein Sendebyte frei hat und wenn im Empfangsbyte etwas ist, was in den "großen" 64 byte Empfangspuffer geschoben werden kann.

So werden da auch Reaktionszeiten unter 40 µs (250000 Baud) möglich.
Das fehlt bei deiner eigenen Implementation noch.

Nunja...
Entweder Interrupts, oder ein rasend schnelles Polling, würde ich mal sagen....

Ja nun, wer wollte da widersprechen :wink:

Ich frage mich:

  • Gibt es kein ordentliches HardwareSerial für attiny841, wo dieses Standard-Problem schon gelöst ist?
  • Wer braucht schon 250000 Bd ?

Hallo,

250kBaud brauche ich. :slight_smile:

Hardware Serial kann der ATtiny schon. Da nun alles darauf hinausläuft das ich Interrupts verwenden muss, stand die Frage selber umbauen oder was fertiges suchen. Dabei stieß ich auf die uart Lib von Peter Fleury. Die Headerdatei habe ich um den ATtiny841 ergänzt und wollte nun ganz einfach anfangen. Ich scheitere aber schon an der Benutzung der Lib. Im Grunde stehen da nur Macros und Funktionen drin. Kein Konstruktor oder dergleichen. Ich weiß trotz der kompletten Beschreibung nicht wie ich eine UART nun wirklich initialisieren soll und die Baudrate einstellen. Einfachste Dinge und ich raff es nicht. Auch mit Google Hilfe kompilieren die gefundenen Schnipsel nicht.

http://homepage.hispeed.ch/peterfleury/doxygen/avr-gcc-libraries/group__pfleury__uart.html

#include <avr/io.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include <uart.h>

#define F_CPU 8000000UL  // Systemtakt in Hz

#define UART_BAUD_RATE 9600   

int main(void)
{   
	uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
			 
    while (1) 
    {
    }
}

Atmel Studio meldet
Fehler undefined reference to `uart_init(unsigned int)'
Fehler recipe for target 'ATtiny841_uart-Lib_001.elf' failed
Fehler ld returned 1 exit status

Die Macros erschlagen mich ehrlich gesagt. Kennt die Lib zufällig jemand von euch?

Edit:
Selbst sowas einfaches wie die RX-Buffergröße zu definieren klappt auch nicht. Default sind 32.

#include <avr/io.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include <uart.h>

#define F_CPU 8000000UL  // Systemtakt in Hz

#define UART_RX_BUFFER_SIZE 20

int main(void)
{   
				 
    while (1) 
    {
    }
}

Atmel Studio meldet:
Warnung "UART_RX_BUFFER_SIZE" redefined
Nachricht this is the location of the previous definition

in der uart.h steht das drin

#ifndef UART_RX_BUFFER_SIZE
#define UART_RX_BUFFER_SIZE 32
#endif

Momentan verstehe ich mal wieder die Welt nicht.

Hardware Serial kann der ATtiny schon

Wenn er mit 8 oder 16 MHz läuft und Interrupts verwendet, sollte dessen HardwareSerial auch 250000 Bd können.

Was ist schlecht an diesem HardwareSerial?
Warum nimmst du es nicht?
Muss ich den ganzen Thread nochmal aufmerksam lesen, um das rauszufinden?
Hast schon seit Anfang auf der attiny Seite mit UART Registern rumgefummelt...

Hallo,

mal ganz sachte. Ich habe nie gesagt das Hardware Serial schlecht ist. Ich nutze sie ja auch nur eben ohne Interrupt derzeit.
Ich habe mich mit den ATtiny UARTs beschäftigt, das Datenblatt herangezogen und etwas Internetrecherche.
Ich hatte nicht weiter nachgedacht und Atmel vertraut das die Bsp. perfekt sind.
Nun wie festgestellt, muss ich Interrupts verwenden. Soweit ist alles klar.
An dem Punkt nun dachte ich, entweder schreibste alles nochmal um oder nimmst doch noch eine fremde Lib.
So wie ich dich nun verstehe soll ich meine Funktionen selbst auf Interrupt Nutzung umschreiben.
Eigentlich wollte ich die Lib nutzen.

Auch wenn ich jetzt ein bisschen pingelig erscheine...
Der Tiny hat keine UART.
Auch keine 2 UARTs.

Im Grunde ist die falsche Benennung kein Problem, wenn man das richtige tut.
Aber mich bringt es, beim lesen von (Programm)Texten, immer wieder zum straucheln.
Ich glaube, dass auch Google viel auskunftsfreudiger ist, wenn man nach den richtigen Begriffen sucht.
Also nicht UART, sondern USART

Hier evtl was anpassungsfähiges.
Zumindest die empfangs ISR ist schon implementiert

Hallo,

ihr drängt mich nun doch selbst umzuschreiben. :wink:
UART, USART, ja okay hat eine USART, wie der Mega.
Standardmäßig wird die im Arduino asyncron betrieben, wenn ich das richtig erkannt habe.

Ja, ein bisschen pingelig bin ich ja schon...
Sachte ich ja schon....

Standardmäßig wird die im Arduino asyncron betrieben, wenn ich das richtig erkannt habe.

Yes.

ihr drängt mich nun doch selbst umzuschreiben.

Kannste so nicht sehen....
Mir ist es recht wurscht, was du tust...
Also, "wurscht", nicht im Sinne von "Gleichgültig", sondern im Sinne von "Selbst verantwortlich".

Und, wenn du es selber schreibst, will ich da gerne mal drüber schauen...
Testen kann ich leider nicht, kein 841 im Haus.

mal ganz sachte. Ich habe nie gesagt das Hardware Serial schlecht ist.

Mein Einwand kam evtl. gestern abend falsch rüber:

Wenn es dein Ziel ist, das selber zu schreiben, sehr schön.
Man sollte sich aber schon ansehen, was es bereits gibt.

Und wenn das Ergebnis dann noch besser wird als das bereits vorhandene (in welcher Hinsicht auch immer), wären ich und wohl auch andere interessiert daran, was du combie zum Drüberschauen gibst.

Hallo,

@ all: gut, dann spornt mich das an nun selbst zu machen. :wink:

@ Micha, kam wohl doch etwas missverstanden rüber., alles gut, keine Sorge.

ab jetzt nicht stören ... :grin: