INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Due: seltsamer Compiler-error mit lib - sonst gings immer
27.04.2015, 14:24 (Dieser Beitrag wurde zuletzt bearbeitet: 27.04.2015 14:33 von HaWe.)
Beitrag #1
Bug Due: seltsamer Compiler-error mit lib - sonst gings immer
Hallo,
ich benutze Sketch 1.6.1 und habe folgende lib eingebunden im Arduino-Installationsordner:

ardustdio.h in Ordner [ardustdio]
Code:
#ifndef  ARDUSTDIO_H
#define ARDUSTDIO_H


//********************************************************************************​?***********

#ifdef __SAM3X8E__

long fscanf_ ( File * stream, const char fmtstr[], ... ) {
   const  int32_t   MAXSTRSIZE = 1024;
   char   str[MAXSTRSIZE];
   va_list   args;
   int32_t   i=0, cnt=0;
   int16_t   chr;

   va_start(args, fmtstr);

   strcpy(str, "");
   while ( (stream->available()) && (i < MAXSTRSIZE-1) ) {  
      chr = stream->read() ;
      if (chr>=0 && chr!='\n') {
           str[i]=(char)chr;    
           ++i;
      }
      else break;    
   }

   str[++i] = '\0';
   // #debug
   // Serial.print("fscanstr:"); Serial.println(str);
                                                        
   cnt = vsscanf( str, fmtstr, args );
   va_end(args);

   return cnt;
}

#endif


//********************************************************************************​?***********

long fprintf_ ( File * stream, const char fmtstr[], ... ) {
   char      str[1024];
   va_list   args;
   int32_t   num;
  
   va_start( args, fmtstr );
   num = vsnprintf(str, sizeof(str), fmtstr, args);
   stream->print(str);
   // #debug

   va_end( args );
   Serial.print("fprintf_:"); Serial.println(str);
   return num;
}

//********************************************************************************​?***********



char * fgets_ ( char * str, int32_t num, File * stream ) {
  int32_t i = 0;

  strcpy(str, "");
  while ( (stream->available()) && (i < num-1) ) {
    int16_t ch = stream->read();
    if (ch < 0)     // end of file
      break;
    str[i++] = ch;
    if ('\n' == ch) // end of line
      break;
  }

  if (i) {          // room in buffer for terminating null
    str[i] = 0;
    return str;
  }
  else
  // return NULL;                  // buffer too small or immediate end of file
  { strcpy(str, ""); return str; } // alternative: return ""
}




//********************************************************************************​***********


char * ftoa(char * str, double f, int16_t precision)
{
  int32_t  p[] = {0,10,100,1000,10000,100000,1000000,10000000,100000000};
  int32_t  intnum, decimal;
  
  char * sret = str;

  if(precision>8) precision=8;
  
  intnum = (long)f;
  itoa( intnum, str, 10);
  
  while ( *str != '\0') str++;
  *str++ = '.';
  
  decimal = abs( (long)( (f - intnum ) * p[precision]) );  
  itoa( decimal, str, 10);

  return sret;
}


//********************************************************************************​***********

#endif



mit diesem SD-testcode funktioniert sie bestens:
Code:
/*
SD card: fprintf_() und fscanf_()
ver 1.02
*/

#include <SPI.h>
#include <SD.h>
#include <ardustdio.h>



// SD Card
#define SD_CSpin 4
File myFile;
char fname[64];

char sdata[128];
char sbuf[128];




void setup()
{
  int32_t  p, i, cnt;
  char     sval[20];
  int32_t  ival, n, m;
  float   fval, x, y;
  // alternativ, ohne jeden Effekt: float   fval, x, y;

  pinMode(SD_CSpin, OUTPUT);
  Serial.begin(9600);

  sprintf(sbuf,"#: SD Initializing... ");
  Serial.println(sbuf);

  while(!SD.begin(SD_CSpin) ) {
    sprintf(sbuf,"#: ...SD init failed ");
    Serial.println(sbuf);
    delay(1000);
  }

  sprintf(sbuf,"#: ...SD OK !      ");
  Serial.println(sbuf);
  strcpy(fname,"test.txt");

  if (SD.exists(fname) ) {
    sprintf(sbuf,"#: %s exists     ",fname);
    Serial.println(sbuf);
  
    sprintf(sbuf,"#: Removing %s      ",fname);
    Serial.println(sbuf);
  
    SD.remove("test.txt");
    // removed: success ?
    if (SD.exists(fname) ) {
       sprintf(sbuf,"#: %s  exists     ",fname);
       Serial.println(sbuf);
    }
    else {
       sprintf(sbuf,"#: %s  N/A     ",fname);
       Serial.println(sbuf);
     }
  }
  



  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open(fname, FILE_WRITE);

  if (myFile) {
    // if the file opened okay, write to it, then close file:
    sprintf(sbuf,"#: Writing strings to %s ",fname);
    Serial.println(sbuf);
  
    //---------------------------------------------------------------------------------
    // write data to file
    fprintf_(&myFile, "%d %d %f %f\n",  1, 2, PI, 4.567890);  
    //---------------------------------------------------------------------------------

    // close the file:
    myFile.close();
    sprintf(sbuf,"#: %s closed.   ",fname);
    Serial.println(sbuf);
  }
  else {
    // if the file didn't open, print an error:
    sprintf(sbuf,"#: error opening %s   ",fname);
    Serial.println(sbuf);    
  }





  // re-open the file for reading:
  Serial.println();

  myFile = SD.open(fname);
  if (myFile) {
    sprintf(sbuf,"#: reading %s ",fname);
    Serial.println(sbuf);
  
    // read from the file until there's nothing else in it:
    i=0;
    cnt=0;
    strcpy(sdata, "");
  
    //---------------------------------------------------------------------------------
    cnt = fscanf_(&myFile, "%d %d %f %f", &m, &n, &x, &y);
    //---------------------------------------------------------------------------------
                          
    Serial.println("# nach Aufruf cnt=fscanf_ im Hauptprogramm");  
       // Testausgabe:
       Serial.print("returned cnt="); Serial.println(cnt);  
       Serial.println();
       Serial.println("returned reformatted variables m,n,x,y:");
       Serial.println(m);
       Serial.println(n);
       Serial.println(x);
       Serial.println(y);

  
    // close the file:
    myFile.close();      
    sprintf(sbuf,"#: %s closed. ",fname);
    Serial.println(sbuf);    
  } else {
    // if the file didn't open, print an error:
    sprintf(sbuf,"#: error opening %s   ",fname);    
    Serial.println(sbuf);

  }
}

void loop()
{
  // nothing happens after setup
}





aber mit dem nächsten, unten stehenden Programm bekomme ich massive unverständliche Fehlermeldungen - was ist da los??

Zitat:Arduino: 1.6.1 (Windows 7), Platine: "Arduino Due (Programming Port)"

Build-Optionen wurden verändert, alles wird neu gebaut

In file included from BPN0011.ino:10:0:

C:\Program Files (x86)\Arduino\libraries\ardustdio/ardustdio.h:9:16: error: 'File' was not declared in this scope

long fscanf_ ( File * stream, const char fmtstr[], ... ) {

^

C:\Program Files (x86)\Arduino\libraries\ardustdio/ardustdio.h:9:23: error: 'stream' was not declared in this scope

long fscanf_ ( File * stream, const char fmtstr[], ... ) {

^

C:\Program Files (x86)\Arduino\libraries\ardustdio/ardustdio.h:9:31: error: expected primary-expression before 'const'

long fscanf_ ( File * stream, const char fmtstr[], ... ) {

^

C:\Program Files (x86)\Arduino\libraries\ardustdio/ardustdio.h:9:52: error: expected primary-expression before '...' token

long fscanf_ ( File * stream, const char fmtstr[], ... ) {

^

C:\Program Files (x86)\Arduino\libraries\ardustdio/ardustdio.h:9:56: error: expression list treated as compound expression in initializer [-fpermissive]

long fscanf_ ( File * stream, const char fmtstr[], ... ) {

^

C:\Program Files (x86)\Arduino\libraries\ardustdio/ardustdio.h:9:58: error: expected ',' or ';' before '{' token

long fscanf_ ( File * stream, const char fmtstr[], ... ) {

^

In file included from C:\Program Files (x86)\Arduino\hardware\arduino\sam\cores\arduino/Arduino.h:203:0,

from C:\Program Files (x86)\Arduino\hardware\arduino\sam\variants\arduino_due_x/variant.h:36,

from C:\Program Files (x86)\Arduino\hardware\arduino\sam\libraries\SPI/SPI.h:15,

from BPN0011.ino:11:

C:\Program Files (x86)\Arduino\hardware\arduino\sam\cores\arduino/USB/USBCore.h:128:8: error: expected declaration before end of line

_Pragma("pack(1)")

^

Fehler beim Kompilieren.



dies ist das Programm, das plötzlich Probleme mit der lib macht (ohne die lib funktioniert das Programm)
Code:
/*
Backpropagation Netz / net
optimiert für Arduino Due
Version BPN 0011
*/

//#include <stdio.h>
//#include <stdlib.h>
//#include <malloc.h>
#include <ardustdio.h>
#include <SPI.h>
#include <SD.h>
#include <UTFT.h>


//-------------------------------------------------------------------------------------
// TFT LCD
//UTFT   myGLCD(Model, SDA=MISO, SCL, CS, RESET, RS)
  UTFT   myGLCD(QD220A,   A2,    A1,  A5,  A4,   A3);   // adjust model parameter and pins !
//UTFT   myGLCD(QD220A,   43,    42,  41,   0,   40);  
//UTFT   myGLCD(QD220A,   41,    40,  43,   0,   42);  
extern   uint8_t SmallFont[];

//-------------------------------------------------------------------------------------
char sbuf[512];  // output string

//-------------------------------------------------------------------------------------
// SD Card
#define  SD_CSpin 4
File     myFile;
char     fname[64];
//-------------------------------------------------------------------------------------
// misc
#define  TimerMS()    millis()
#define  LRAND_MAX    32767
#define  srand(seed)  randomSeed(seed)
#define  rand()       random(LRAND_MAX)  
#define  rando()      ((float)rand()/(LRAND_MAX+1))
int32_t  RSeed;

//-------------------------------------------------------------------------------------
// neural net
#define  NUMIN      8
#define  NUMHID     6
#define  NUMOUT    10
#define  NUMPAT   128

float    Input[NUMPAT+1][NUMIN+1];
float    Target[NUMPAT+1][NUMOUT+1];
float    WeightLIn[NUMIN+1][NUMHID+1];
float    WeightLOut[NUMHID+1][NUMOUT+1], Output[NUMPAT+1][NUMOUT+1];

int16_t  NumPattern = NUMPAT, NumInput = NUMIN, NumHidden = NUMHID, NumOutput = NUMOUT;
int32_t  epoch;
//-------------------------------------------------------------------------------------


//================================================================================​=====
void setup() {  
   Serial.begin(9600);
      
   myGLCD.InitLCD();
   myGLCD.setFont(SmallFont);
   myGLCD.clrScr();
  
   sprintf(sbuf, "#: Serial() + GLCD started");
   Serial.println(sbuf);
   myGLCD.print  (sbuf, 0, 0);
  
   RSeed = ( ((analogRead(A8)+1001)%100) * (TimerMS() ) % LRAND_MAX );
   srand(RSeed);
   sprintf(sbuf, "RandomSeed= %ld", RSeed);
   myGLCD.print  (sbuf, 0,10);  
   sprintf(sbuf, "RandomTest= %ld", rand() );
   myGLCD.print  (sbuf, 0,20);

}
//================================================================================​=====




/*******************************************************************************
*   Backpropagation-C-Implementierung:  nn.c   1.0 (C) JOHN BULLINARIA  2004   *
*   verändert und portiert auf Arduino Sketch C: HELMUT WUNDER ("HaWe") 2015   *
*******************************************************************************/

//================================================================================​=====
void ResetNet(){
  
   for(int i=0; i<= NUMIN; ++i) {
      for(int j=0; j<= NUMIN; ++j) {
         Input[j][i] = 0;
      }
   }
  
   for(int i=0; i<= NUMPAT; ++i) {
      for(int j=0; j<= NUMIN; ++j) {
         Target[j][i] = 0;
      }
   }
  
  
}
//================================================================================​=====



//================================================================================​=====
void PutNet(){
  
    Input[1][1] = 0;
    Input[1][2] = 0;
    Input[1][3] = 0;
    Target[1][1] = 0; Target[1][2] = 0; Target[1][3] = 0; Target[1][4] = 0; Target[1][5] = 0;
    
    Input[2][1] = 0;
    Input[2][2] = 0;
    Input[2][3] = 1;
    Target[2][1] = 1; Target[2][2] = 0; Target[2][3] = 1; Target[2][4] = 0; Target[2][5] = 0;
    
    Input[3][1] = 0;
    Input[3][2] = 1;
    Input[3][3] = 0;
    Target[3][1] = 1; Target[3][2] = 0; Target[3][3] = 0; Target[3][4] = 0; Target[3][5] = 0;
    
    Input[4][1] = 0;
    Input[4][2] = 1;
    Input[4][3] = 1;  
    Target[4][1] = 0; Target[4][2] = 1; Target[4][3] = 1; Target[4][4] = 1; Target[4][5] = 0;
    
    Input[5][1] = 1;
    Input[5][2] = 0;
    Input[5][3] = 0;
    Target[5][1] = 0; Target[5][2] = 0; Target[5][3] = 0; Target[5][4] = 0; Target[5][5] = 0;
    
    Input[6][1] = 1;
    Input[6][2] = 0;
    Input[6][3] = 1;
    Target[6][1] = 1; Target[6][2] = 1; Target[6][3] = 1; Target[6][4] = 1; Target[6][5] = 0;
    
    Input[7][1] = 1;
    Input[7][2] = 1;
    Input[7][3] = 0;
    Target[7][1] = 1; Target[7][2] = 1; Target[7][3] = 0; Target[7][4] = 1; Target[7][5] = 0;
    
    Input[8][1] = 1;
    Input[8][2] = 1;
    Input[8][3] = 1;
    Target[8][1] = 0; Target[8][2] = 0; Target[8][3] = 1; Target[8][4] = 1; Target[8][5] = 1;

}

//================================================================================​=====
uint32_t BPTime;

void DisplayNetOut() {
    int16_t   i, k, p;
      
    /* print network outputs */  
    sprintf(sbuf, "\n\nBP NET DATA:   EPOCH = %ld  ", epoch) ; Serial.print(sbuf);  
    sprintf(sbuf,   "\nBP NET TRAINING TIME = %ld sec \n", BPTime/1000);   Serial.print(sbuf);                                                      
    
    sprintf(sbuf, "\nPat   ") ; Serial.print(sbuf);  
    for( i = 1 ; i <= NumInput ; i++ ) {
        sprintf(sbuf, "Inp%-3d ", i) ;  Serial.print(sbuf);
    }
    for( k = 1 ; k <= NumOutput ; k++ ) {
        sprintf(sbuf, "Targ%-3d Outp%-3d ", k, k); Serial.print(sbuf);
    }
    for(int p = 1 ; p <= NumPattern ; p++ ) {        
    sprintf(sbuf, "\n%3d  ", p) ;  Serial.print(sbuf);
        for( i = 1 ; i <= NumInput ; i++ ) {
            sprintf(sbuf, "%5.2f  ", Input[p][i]) ; Serial.print(sbuf);
        }
        for( k = 1 ; k <= NumOutput ; k++ ) {
            sprintf(sbuf, "%5.2f   %5.2f   ", Target[p][k], Output[p][k]) ;  Serial.print(sbuf);
        }
    }
    sprintf(sbuf, "\n\nBPNet computed!\n\n") ;  Serial.print(sbuf);  
  
}
//================================================================================​=====


int16_t  TrainBPNet() {
    int16_t  i, j, k, p, np, op, ranpat[NUMPAT+1], result=0;
    int32_t  offset=0;        
    float    SumH[NUMPAT+1][NUMHID+1];
    float    SumO[NUMPAT+1][NUMOUT+1];
    float    HidOut[NUMPAT+1][NUMHID+1];
    float    DeltaO[NUMOUT+1], SumDOW[NUMHID+1], DeltaH[NUMHID+1];
    float    DeltaWeightLIn[NUMIN+1][NUMHID+1], DeltaWeightLOut[NUMHID+1][NUMOUT+1];
    float    Error, eta = 0.5, alpha = 0.9, smallwt = 0.5;
  
    sprintf(sbuf, "\n\nBP NET TRAINING started\n\n") ;  Serial.print(sbuf);
    uint32_t TimeStamp=TimerMS();
    
populate:  
    for( j = 1 ; j <= NumHidden ; j++ ) {    /* initialize WeightLIn and DeltaWeightLIn */
        for( i = 0 ; i <= NumInput ; i++ ) {
            DeltaWeightLIn[i][j] = 0.0 ;
            WeightLIn[i][j] = 2.0 * ( rando() - 0.5 ) * smallwt ;
        }
    }
    for( k = 1 ; k <= NumOutput ; k ++ ) {    /* initialize WeightLOut and DeltaWeightLOut */
        for( j = 0 ; j <= NumHidden ; j++ ) {
            DeltaWeightLOut[j][k] = 0.0 ;              
            WeightLOut[j][k] = 2.0 * ( rando() - 0.5 ) * smallwt ;
        }
    }
    
    for( epoch = 0 ; epoch <= 500000 ; epoch++) {    /* iterate weight updates */
        for( p = 1 ; p <= NumPattern ; p++ ) {    /* randomize order of individuals */
            ranpat[p] = p ;
        }
        for( p = 1 ; p <= NumPattern ; p++) {
            np = p + rando() * ( NumPattern + 1 - p ) ;
            op = ranpat[p] ; ranpat[p] = ranpat[np] ; ranpat[np] = op ;
        }
        Error = 0.0 ;
        for( np = 1 ; np <= NumPattern ; np++ ) {    /* repeat for all the training patterns */
            p = ranpat[np];
            for( j = 1 ; j <= NumHidden ; j++ ) {    /* compute hidden unit activations */
                SumH[p][j] = WeightLIn[0][j] ;
                for( i = 1 ; i <= NumInput ; i++ ) {
                    SumH[p][j] += Input[p][i] * WeightLIn[i][j] ;
                }
                HidOut[p][j] = 1.0/(1.0 + exp(-SumH[p][j])) ;
            }
            for( k = 1 ; k <= NumOutput ; k++ ) {    /* compute output unit activations and errors */
                SumO[p][k] = WeightLOut[0][k] ;
                for( j = 1 ; j <= NumHidden ; j++ ) {
                    SumO[p][k] += HidOut[p][j] * WeightLOut[j][k] ;
                }
                Output[p][k] = 1.0/(1.0 + exp(-SumO[p][k])) ;   /* Sigmoidal Outputs */
/*              Output[p][k] = SumO[p][k];      Linear Outputs */
                Error += 0.5 * (Target[p][k] - Output[p][k]) * (Target[p][k] - Output[p][k]) ;   /* SSE */
/*              Error -= ( Target[p][k] * log( Output[p][k] ) + ( 1.0 - Target[p][k] ) * log( 1.0 - Output[p][k] ) ) ;    Cross-Entropy Error */
                DeltaO[k] = (Target[p][k] - Output[p][k]) * Output[p][k] * (1.0 - Output[p][k]) ;   /* Sigmoidal Outputs, SSE */
/*              DeltaO[k] = Target[p][k] - Output[p][k];     Sigmoidal Outputs, Cross-Entropy Error */
/*              DeltaO[k] = Target[p][k] - Output[p][k];     Linear Outputs, SSE */
            }
            for( j = 1 ; j <= NumHidden ; j++ ) {    /* 'back-propagate' errors to hidden layer */
                SumDOW[j] = 0.0 ;
                for( k = 1 ; k <= NumOutput ; k++ ) {
                    SumDOW[j] += WeightLOut[j][k] * DeltaO[k] ;
                }
                DeltaH[j] = SumDOW[j] * HidOut[p][j] * (1.0 - HidOut[p][j]) ;
            }
            for( j = 1 ; j <= NumHidden ; j++ ) {     /* update weights WeightLIn */
                DeltaWeightLIn[0][j] = eta * DeltaH[j] + alpha * DeltaWeightLIn[0][j] ;
                WeightLIn[0][j] += DeltaWeightLIn[0][j] ;
                for( i = 1 ; i <= NumInput ; i++ ) {
                    DeltaWeightLIn[i][j] = eta * Input[p][i] * DeltaH[j] + alpha * DeltaWeightLIn[i][j];
                    WeightLIn[i][j] += DeltaWeightLIn[i][j] ;
                }
            }
            for( k = 1 ; k <= NumOutput ; k ++ ) {    /* update weights WeightLOut */
                DeltaWeightLOut[0][k] = eta * DeltaO[k] + alpha * DeltaWeightLOut[0][k] ;
                WeightLOut[0][k] += DeltaWeightLOut[0][k] ;
                for( j = 1 ; j <= NumHidden ; j++ ) {
                    DeltaWeightLOut[j][k] = eta * HidOut[p][j] * DeltaO[k] + alpha * DeltaWeightLOut[j][k] ;
                    WeightLOut[j][k] += DeltaWeightLOut[j][k] ;
                }
            }
        }
        if( epoch % 20 == 0 )
        {
           sprintf(sbuf, "\nEpoch %-7ld :   Error = %11.9f", epoch, Error) ;  Serial.print(sbuf);
        }

        if( Error < 0.005 ) break ;  /* stop learning when 'near enough' */
    }
    
    result=1;
    BPTime = TimerMS() - TimeStamp;
    return result ;
}

/*******************************************************************************/



//================================================================================​=====
void loop() {
   int16_t IOResult;
  
   ResetNet();
   PutNet();
   IOResult=TrainBPNet();
   if (IOResult==1)  DisplayNetOut();
   else {sprintf(sbuf, "\n\nBP NET COMPUTING ERROR !!\n\n") ;  Serial.print(sbuf);}
  
   sprintf(sbuf, "\n\nGoodbye!\n\n") ;  Serial.print(sbuf);
  
   while(1);  

}
//================================================================================​=====
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
27.04.2015, 16:59
Beitrag #2
RE: Due: seltsamer Compiler-error mit lib - sonst gings immer
seltsam...
habe den Code jetzt schrittweise aus einer älteren Version wieder hergestellt samt der zuletzt gemachten Änderungen -
und jetzt gehts plötzlich wieder.
Möglicherweise irgendwelche Index-Dreher etc.. Naja, Hauptsache, es geht.
8-)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  Ausgabe druckt immer 2 Werte anstatt nur einen. Finde den Fehler nicht TimeMen 24 743 02.07.2016 14:18
Letzter Beitrag: hotsystems
  Wieso immer int ? Mathias 7 343 12.06.2016 17:23
Letzter Beitrag: Mathias
  Display Blinkt immer arduino_weatherstation 29 1.628 12.03.2016 13:10
Letzter Beitrag: hotsystems
  Frage zum Arduino Studio Compiler avoid 1 489 27.02.2016 09:15
Letzter Beitrag: amithlon
  Hexzahl immer mit 2 Zeichen ausgeben. arduinofan 11 793 12.01.2016 09:00
Letzter Beitrag: arduinofan
Question Blind wie immer???? :P Hilgi 4 557 09.11.2015 03:28
Letzter Beitrag: Hilgi
  ESP8266 error: espcomm_open failed Stefan570 3 5.705 22.05.2015 13:03
Letzter Beitrag: Stefan570
  Error mit Arduino Mega NicoZ 7 2.993 19.05.2015 21:33
Letzter Beitrag: NicoZ
  seltsamer Effekt bei LCD-TFT mit GLCD-Funktion HaWe 13 1.165 06.05.2015 07:58
Letzter Beitrag: HaWe
  bei Tastendruck Variable immer +1 matze.lingen 8 3.431 04.05.2015 13:45
Letzter Beitrag: SkobyMobil

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste