Autor Tema: Velocidad actualizacion LCD 4x20  (Leído 1771 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado ktg

  • PIC10
  • *
  • Mensajes: 3
Velocidad actualizacion LCD 4x20
« en: 19 de Octubre de 2012, 04:33:27 »
Hola a todos y mil gracias por vuestra ayuda.

Estoy desarrolando un controlador de motores paso a paso basado en un pic 18F4458 y un LCD 4x20 compatible con HD44780. Estoy utilizando la libreria Flex 4x20 publicada en el foro de CCS y todo "parece" funcionar correctamente. El problema surge con la velocidad de actualización del LCD.
Después de realizar varias pruebas y ejecutar el programa en modo "release" ( directametne sobre el micro, sin el debugger ) el tiempo de actualización del LCd es de unos 5 segundos!

Tengo un cristal de 48MHz y todo parece correcto, pero no se que estoy programando mal, no puedo creerme que los tiempos de actualización de este tipo de LCD sean de este nivel.

Adjunto los archivos Main.c Driver LCD y Config IO.h comprimidos. No se como publicarlos en el cuerpo del mensaje que no sea un "copy" - "paste"

Mil gracias otra vez por vuestra ayuda.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Velocidad actualizacion LCD 4x20
« Respuesta #1 en: 19 de Octubre de 2012, 09:43:57 »
  Para colocarlos directamente en el cuerpo del mensaje tienes la opción GeSHi, allí eliges el lenguaje y luego sí copias tu código dentro de ese bloque.


Ejemplo


Código: C
  1. /**************************************************************************
  2. *          Libreria para protocolo I2C por HardWare para HiTech           *
  3. ***************************************************************************
  4.  
  5. ***************************************************************************
  6. *                                                                         *
  7. * Antes de incluir este archivo en nuestro programa hay que definir       *
  8. * algunos parametros. Estos son                                           *
  9. *                                                                         *
  10. * _XTAL_FREQ     (se usa para calcular el valor de SSPADD)                *    
  11. * I2C_BAUD       (velocidad de transferencia)                             *
  12. *                                                                         *
  13. ***************************************************************************
  14.  
  15. ***************************************************************************
  16. *                                                                         *
  17. *  Los pines correspondientes a SCL y SDA deben ser configurados como     *
  18. * entradas                                                                *
  19. *                                                                         *
  20. ***************************************************************************
  21.  
  22. ***************************************************************************
  23. *                                                                         *
  24. * En esta libreria se encuentran las siguientes funciones                 *
  25. *                                                                         *
  26. * setup_i2c(char)               (inicializa el puerto I2C)                *
  27. * start_i2c()                   (envia start, inicia transmision)         *
  28. * rstar_i2c()                   (envia restart, reinicia transmision)     *
  29. * stop_i2c()                    (envia stop, termina transmision)         *
  30. * write_i2c(char)               (envia un byte)                           *
  31. * read_i2c(char)                (recibe un byte y envia ack o noack)      *
  32. *                                                                         *
  33. *  La funcion write_i2c() devuelve 0 si el dispositivo responde o 1 si el *
  34. * dispositivo no responde.                                                *
  35. *                                                                         *
  36. *  A la funcion read_i2c() hay que pasarle 0 si se quiere responder al    *
  37. * disipositivo o 1 si no se quiere responder                              *
  38. *                                                                         *
  39. *  En esta libreria estan definidos los parametros I2C_MASTER, I2C_SLAVE, *
  40. * I2C_10BIT_ADDRESS, DISABLE.                                             *
  41. * Eston son utilizados en la funcion setup_i2c(char)                      *
  42. *                                                                         *
  43. *  Tambien estan definidos ACK y NACK que son los utilizados para         *
  44. * responder o no al dispositivo                                           *
  45. *                                                                         *
  46. ***************************************************************************
  47.  
  48. * Ejemplo de configuracion y utilizacion
  49.  
  50.  #define _XTAL_FREQ   10000000   // cristal 10MHz
  51.  #define I2C_BAUD  100000     // velocidad 100 KHz
  52.  #include "HardI2c.c"
  53.  
  54.  void main (void);
  55.  {
  56.    unsigned char respuesta;
  57.    unsigned char dato;  
  58.  
  59.    ......
  60.    ......
  61.    ......
  62.    TRISC4 = 1;
  63.    TRISC5 = 1;
  64.    setup_i2c (I2C_MASTER);
  65.    start_i2c();
  66.    respuesta = write_i2c (0b10101110);    // comunicacion para escribir en una 24C02C
  67.    if (respuesta == ACK)
  68.    {
  69.      write_i2c (0x00);                    // indico la direccion a escribir
  70.      write_i2c (0xF5);                    // escribo el dato F5
  71.      write_i2c (0x06);                    // escribo el dato 06
  72.    }
  73.    stop_i2c();
  74.  
  75.    // colocar un delay necesario para que termine de grabar la memoria
  76.  
  77.    start_i2c();
  78.    respuesta = write_i2c (0b10101110);    // comunicacion para escribir en una 24C02C
  79.    if (respuesta == ACK)
  80.    {
  81.      write_i2c (0x00);                    // indico la direccion de memoria
  82.      rstart_i2c();                       // reinicio la transmisión
  83.      respuesta = write_i2c (0b10101111);  // comunicacion para leer en una 24C02C
  84.      if (respuesta == ACK)
  85.      {
  86.        dato = read_i2c (ACK);             // leo el dato y respondo
  87.        dato = read_i2c (NACK);           // leo el dato y no respondo
  88.      }
  89.    }
  90.    stop_i2c();
  91.  }
  92.  
  93. */
  94.  
  95. #if defined (_XTAL_FREQ) && defined (I2C_BAUD)
  96.  
  97.   #define I2C_MASTER          0x38
  98.   #define I2C_SLAVE           0x26
  99.   #define I2C_10BIT_ADDRESS   0x01
  100.  
  101.   #ifndef DISABLE
  102.     #define DISABLE 0
  103.   #endif
  104.   #ifndef ACK
  105.     #define ACK 0
  106.   #endif
  107.   #ifndef NACK
  108.     #define NACK 1
  109.   #endif
  110.  
  111. /*
  112.   #ifndef RW
  113.     #define RW R_nW
  114.   #endif
  115.   #ifndef DA
  116.     #define DA D_nA
  117.   #endif
  118.  
  119.  
  120.   #ifndef SSPCON
  121.     #define SSPCON SSPCON1
  122.   #endif
  123. */
  124.  
  125.   void setup_i2c (char x)
  126.   {
  127.     SSPSTAT = 0;
  128.     SSPCON = x;
  129.     SSPCON2 = 0;
  130.     if (SSPM3 == 1) SSPADD = (unsigned char)((_XTAL_FREQ/(4UL*I2C_BAUD)) - 1);
  131.   }
  132.  
  133.   char start_i2c (void)
  134.   {
  135.     while (( SSPCON2 & 0x1F ) || RW );
  136.     SEN = 1;
  137.     return !BCLIF;
  138.   }
  139.  
  140.   void rstart_i2c (void)
  141.   {
  142.     while (( SSPCON2 & 0x1F ) || RW );
  143.     RSEN = 1;
  144.   }
  145.  
  146.   void stop_i2c (void)
  147.   {
  148.     while (( SSPCON2 & 0x1F ) || RW );
  149.     PEN = 1;
  150.   }
  151.  
  152.   char write_i2c (unsigned char data)
  153.   {
  154.     if (SSPM3 == 1)
  155.     {
  156.       while (( SSPCON2 & 0x1F ) || RW );
  157.       SSPBUF = data;
  158.       while (RW == 1);
  159.       return ACKSTAT;
  160.     }
  161.     else
  162.     {
  163.       SSPBUF = data;
  164.       CKP = 1;
  165.       return 0;
  166.     }
  167.   }
  168.  
  169.   unsigned char read_i2c (unsigned char respuesta)
  170.   {
  171.     unsigned char dato;
  172.  
  173.     if (SSPM3 == 1)
  174.     {
  175.       while (( SSPCON2 & 0x1F ) || RW );
  176.       RCEN = 1;
  177.       while (( SSPCON2 & 0x1F ) || RW );
  178.       dato = SSPBUF;
  179.       while (( SSPCON2 & 0x1F ) || RW );
  180.       ACKDT = respuesta;
  181.       ACKEN = 1;
  182.       return dato;
  183.     }
  184.     else
  185.     {
  186.       return SSPBUF;
  187.     }
  188.   }
  189. #else
  190.   #error Faltan definir parametros
  191. #endif
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Velocidad actualizacion LCD 4x20
« Respuesta #2 en: 20 de Octubre de 2012, 14:49:04 »
hace un tiempo tuve un problema con un GLCD porque no se pintaban bien los pixeles,  era porque usaba un cristal de 20Mhz, lo solucioné cambiando a 4Mhz pero tambien se solucionaba agregando un retardo en la libreria del GLCD. En el foro hay un hilo por ahi donde comentan donde poner el retardo, de pronto ayuda ya que pones a correr el micro a 48Mhz
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado ktg

  • PIC10
  • *
  • Mensajes: 3
Re: Velocidad actualizacion LCD 4x20
« Respuesta #3 en: 31 de Octubre de 2012, 07:28:22 »
Muchas gracias a todos por vuestros comentarios....

menos al que me vendio un cristal de 48Mhz por uno de.... no lo sabe ni él!

Después de comprobar que el cristal no funciona a la frecuencia deseada, procedo a canviarlo por uno de 20Mhz y ahora la velocidad de actualización es mucho mayor, aunque ahora me he dado cuenta del siente fenomeno.

Si NO ejecuto la actualización del LCD (UpdateLCD), la interrupción del Timer2 funciona correctamente y me da una frecuencia de 1007 Khz. Pero en cuanto ejecuto la rutina de actualización del LCD, deja de ejecutarse la interrupción del Timer2. para poder hacer pruebas, he eliminado tod el codigo sobrante y para la interrupcion del TImer2 cambio el estado de un led (EnableX) y para controlar la frecuencia de actualización del LCD cambio el estado de otro led (EnableY)

La rutina de control de LCD es la coocida como FLEX LCD4x20 extraida del foro de CCS.

Qualquier ayuda sera bien recibida, ya que no termino de encontrar donde esta el error o que me estoy dejando de hacer.

gracias de nuevo.

Aqui les dejo el codigo

Código: C
  1. // ***** FITXERS INCLOSSOS EN EL COMPILADOR *********************************
  2. #include <Config IO.h>
  3. #include <Driver LCD 4x20.C>
  4.  
  5. // ***** DEFINICIONS DEL PROGRAMA *******************************************
  6. #define desactiva   output_low
  7. #define activa      output_high
  8. #define canvia      output_toggle
  9.  
  10. // ***** CONSTANTS DEL PROGRAMA *********************************************
  11. const float   AdvanceX = 160.0;      // RELACIÓ D'AVANÇ - POLSOS x MILIMETRE - EIX X   - M8 = 1,25 mm/360º
  12. const float   AdvanceY = 200.0;      // RELACIÓ D'AVANÇ - POLSOS x MILIMETRE - EIX Y   - M6 = 1 mm/360º  
  13. const float   AdvanceZ = 200.0;      // RELACIÓ D'AVANÇ - POLSOS x MILIMETRE - EIX Z   - M6 = 1 mm/360º
  14.  
  15. // ***** VARIABLES DEL PROGRAMA *********************************************
  16. long     Index = 0;               // INDEX MENU
  17. long     Speed[3] = {25,25,25};      // VELOCITAT EIXOS X-Y-Z
  18. long     Counter[3] = {100,100,100};   // CONTADOR PER GENERAR FRECUENCIA EIXOS X-Y-Z
  19. long     ControlX = 0;            // VALOR CONVERSOR AD CONTROL EIX X
  20. long     ControlY = 0;            // VALOR CONVERSOR AD CONTROL EIX Y
  21. long     ControlZ = 0;            // VALOR CONVERSOR AD CONTROL EIX Z      
  22. float    AkkuABSX = 0.0;            // CONTADOR ACUMULADOR ABSOLUT EIX X
  23. float    AkkuABSY = 0.0;            // CONTADOR ACUMULADOR ABSOLUT EIX Y
  24. float    AkkuABSZ = 0.0;            // CONTADOR ACUMULADOR ABSOLUT EIX Z      
  25. float    PosABSX = 0.0;            // POSICIO EIX X ABSOLUT - MILIMETRES
  26. float    PosABSY = 0.0;            // POSICIO EIX Y ABSOLUT - MILIMETRES
  27. float    PosABSZ = 0.0;            // POSICIO EIX Z ABSOLUT - MILIMETRES
  28. float    MemoryX = 0.0;            // MEMORIA POSICIO RELATIVA EIX X
  29. float    MemoryY = 0.0;            // MEMORIA POSICIO RELATIVA EIX Y
  30. float    MemoryZ = 0.0;            // MEMORIA POSICIO RELATIVA EIX Z      
  31. float    PosRELX = 0.0;            // POSICIO EIX X RELATIU - MILIMETRES
  32. float    PosRELY = 0.0;            // POSICIO EIX Y RELATIU - MILIMETRES
  33. float    PosRELZ = 0.0;            // POSICIO EIX Z RELATIU - MILIMETRES
  34. int      StatusPB = 0;            // VALOR ACTUAL SENYALS EN PORT B
  35. int      LastPB = 0;               // VALOR ANTERIOR SENYALS EN PORT B
  36. int      Enables = 0;            // ESTAT PINS HABILITACIONS EIXOS
  37. int      Directions = 0;            // ESTAT PINS DIRECCIONS EIXOS
  38. short    MotorON = 0;            // HABILITACIO POTENCIA
  39. char     MenuTXT[20] = "";         // TEXTES MENU
  40.  
  41.  
  42. // ***** INTERRUPCIO TIMER 2 - GENERACIO FRECUENCIA
  43. #int_TIMER2
  44. void  TIMER2_isr(void){
  45.    
  46.    canvia(EnableX);
  47.  
  48. }
  49.  
  50. // ***** INICIALIZEM PIC ****************************************************
  51. void InitializePIC (){
  52.  
  53. // CONFIGURACIÓ CANALS ANALÓGICS
  54.       setup_adc_ports(AN0_TO_AN2|VSS_VDD);
  55.       setup_adc(ADC_CLOCK_DIV_2|ADC_TAD_MUL_0);
  56.  
  57. // SERIAL SPI I TEMPORITZADORS INTERNS
  58.       setup_psp(PSP_DISABLED);                        // DESHABILITEM PSP
  59.       setup_spi(SPI_SS_DISABLED);                        // DESHABILITEM SERIAL PORT
  60.       setup_wdt(WDT_OFF);                              // DESHABILITEM WATCHDOG
  61.       setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8|RTCC_8_bit);   // CONFIGURACIO TIMER 0 - 409us 0xFF
  62.       setup_timer_1(T1_DISABLED);                        // CONFIGURACIO TIMER 1
  63.       setup_timer_2(T2_DIV_BY_16,30,5);                  // CONFIGURACIO TIMER 2 - 496uS
  64.       setup_timer_3(T3_DISABLED|T3_DIV_BY_1);               // CONFIGURACIO TIMER 3
  65.  
  66. // CONFIGURACIÓ LCD
  67.       lcd_init();      
  68.  
  69. // CONFIGURACIÓ PORTS DIGITALS        
  70.       port_b_pullups(TRUE);  
  71.  
  72. // INICIALITZACIÓ SENYALS DIGITALS
  73.       desactiva(DirectionX);
  74.       desactiva(DirectionY);
  75.       desactiva(DirectionY);
  76.       desactiva(EnableX);
  77.       desactiva(EnableY);
  78.       desactiva(EnableZ);
  79.       desactiva(Rele);
  80.  
  81. // CONTROL INTERRUPCIONS
  82.       enable_interrupts(INT_TIMER2);
  83.       enable_interrupts(GLOBAL);
  84.    
  85. }
  86.  
  87. // ***** ACTUALITZEM PANTALLA LCD ********************************************
  88. void UpdateLCD (){
  89.    
  90.    PosABSX = (AkkuABSX / AdvanceX);   // POSICIO ABSOLUTA nnn.nn EN mm EIX X
  91.    PosABSY = (AkkuABSY / AdvanceY);   // POSICIO ABSOLUTA nnn.nn EN mm EIX Y
  92.    PosABSZ = (AkkuABSZ / AdvanceZ);   // POSICIO ABSOLUTA nnn.nn EN mm EIX Z
  93.  
  94.    PosRELX = (PosABSX - MemoryX);      // POSICIO RELATIVA nnn.nn EN mm EIX X
  95.    PosRELY = (PosABSZ - MemoryY);      // POSICIO RELATIVA nnn.nn EN mm EIX Y
  96.    PosRELZ = (PosABSZ - MemoryZ);      // POSICIO RELATIVA nnn.nn EN mm EIX Z
  97.  
  98.    switch(Index){                        // CARREGUEM TEXTE MENU
  99.       case 0: MenuTXT =    "CNC V1.0   -Menu-   ";          break;
  100.       case 1: MenuTXT =    "Reiniciar ABS Eix X?";          break;
  101.       case 2: MenuTXT =    "Reiniciar ABS Eix Y?";          break;
  102.       case 3: MenuTXT =    "Reiniciar ABS Eix Z?";          break;
  103.       case 4: MenuTXT =    "Reiniciar ABS Tots? ";          break;
  104.       case 5: MenuTXT =    "Reiniciar REL Eix X?";          break;
  105.       case 6: MenuTXT =    "Reiniciar REL Eix Y?";          break;
  106.       case 7: MenuTXT =    "Reiniciar REL Eix Z?";          break;
  107.       case 8: MenuTXT =    "Reiniciar REL Tots? ";          break;
  108.       case 9: MenuTXT =    "Velocitat % Eix X   ";          break;
  109.       case 10: MenuTXT =   "Velocitat % Eix Y   ";          break;
  110.       case 11: MenuTXT =   "Velocitat % Eix Z   ";          break;
  111.       default:break;}
  112.  
  113.    lcd_gotoxy(1,1);
  114.    printf(lcd_putc, MenuTXT);
  115.    lcd_gotoxy(1,2);
  116.    printf(lcd_putc, "X: %05.2f %05.2f %03Lu",PosABSX,PoSRELX,Speed[0]);
  117.    lcd_gotoxy(1,3);
  118.    printf(lcd_putc, "Y: %05.2f %05.2f %03Lu",PosABSY,PoSRELY,Speed[1]);
  119.    lcd_gotoxy(1,4);
  120.    printf(lcd_putc, "Z: %05.2f %05.2f %03Lu",PosABSZ,PoSRELZ,Speed[2]);            
  121. }
  122.  
  123. // ***** RUTINA PRINCIPAL ****************************************************
  124. void Main(void) {
  125.  
  126.      InitializePIC ();               // INICIALITZEM PIC
  127.  
  128.    while (TRUE){
  129.      UpdateLCD ();
  130.      canvia(EnableY);
  131.    }
  132. }


Para el archivo Config IO.h

Código: C
  1. #include <18F4458.h>
  2. #device ICD=TRUE
  3. #device ADC=12
  4.  
  5. #FUSES NOWDT         //No Watch Dog Timer
  6. #FUSES NOPROTECT     //Code not protected from reading
  7. #FUSES DEBUG         //Debug mode for use with ICD
  8. #FUSES CPUDIV1       //System Clock by 1
  9. #FUSES USBDIV        //USB clock source comes from PLL divide by 2
  10. #FUSES VREGEN        //USB voltage regulator enabled
  11. #FUSES HSPLL         //High Speed Crystal/Resonator with PLL enabled
  12. #FUSES NOLVP         //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
  13. #FUSES PLL5          //Divide By 5(20MHz oscillator input)
  14.  
  15. #use DELAY(CRYSTAL=20Mhz)
  16.  
  17. // CONFIGURACIO HARDWARE
  18.  
  19. // POLSADORS XYZ
  20. // RESISTENCIA PULL UP = 1K0
  21. // RESISTENCIA POLSADOR "AVANÇ" = 499
  22. // RESISTENCIA POLSADOR "RETROCES" = 1K0
  23. // VALOR EN REPOS:    3.0V - 2456
  24. // VALOR AVANÇ:      2.5V - 2048
  25. // VALOR RETROCES:   1.6V - 1363
  26.  
  27. // VERMELL - 11 - +5V
  28. // MALLA - 18 to 25 >> REFERENCIA DE MASA
  29.  
  30. // TARONJA - 10 - VERD >> ENTRADA ORDENADOR
  31. // BLAU - 12 - VERMELL/NEGRE >> ENTRADA ORDENADOR
  32. // BLAU CEL - 13 - GROC >> ENTRADA ORDENADOR
  33. // VERD CLAR - 15 - LILA >> ENTRADA ORDENADOR
  34.  
  35. #define AI0            PIN_A0      // PIN 02 - ANALOG 1 - CONTROL X - GROC POLSADORS
  36. #define AI1            PIN_A1      // PIN 03 - ANALOG 2 - CONTROL Y - BLAU POLSADORS
  37. #define AI2            PIN_A2      // PIN 04 - ANALOG 3 - CONTROL Z - VERD POLSADORS
  38. #define Limit         PIN_A3      // PIN 05 - ENTRADA LIMIT FÍSIC
  39. #define Rele         PIN_A4      // PIN 06 - SORTIDA PER RELE POTENCIA - GROC - 1 - NEGRE
  40. #define LED            PIN_A5      // PIN 07 - SORTIDA LED ERROR - TARONJA/NEGRE - 8 - GRIS
  41.  
  42. #define Motor         PIN_B0      // PIN 33 - POLSADOR MARXA MOTOR [VERMELL] - LILA POLSADORS
  43. #define ESC            PIN_B1      // PIN 34 - POLSADOR SORTIR [GROC] - MARRO - POLSADORS
  44. #define SELECT         PIN_B2      // PIN 35 - POLSADOR SELECT [VERD] - BLANC POLSADORS
  45. #define ENTER         PIN_B3      // PIN 36 - POLSADOR ENCODER ACK
  46. #define EncoderA      PIN_B4      // PIN 37 - ENCODER CANAL A
  47. #define EncoderB      PIN_B5      // PIN 38 - ENCODER CANAL B
  48. #define ICSPClock      PIN_B6      // PIN 39 - ICSP RELLOTGE
  49. #define ICSPData      PIN_B7      // PIN 40 - ICSP DATA
  50.  
  51. #define DirectionX      PIN_C0        // PIN 15 - SORTIDA DIRECCIO X - LILA/BLANC - 5 -      
  52. #define DirectionY       PIN_C1      // PIN 16 - SORTIDA DIRECCIO Y - GRIS - 6 -          
  53. #define DirectionZ       PIN_C2      // PIN 17 - SORTIDA DIRECCIO Z - ROSA - 7 -                
  54. #define USBM          PIN_C4      // PIN 23 - USB DATA -        
  55. #define USBP          PIN_C5      // PIN 24 - USB DATA +                                      
  56. #define ClockX          PIN_C6      // PIN 25 - SORTIDA RELLOTGE X - VERMELL/NEGRE - 2 -                  
  57. #define ClockY           PIN_C7     // PIN 26 - SORTIDA RELLOTGE Y - NEGRE - 3
  58.  
  59. #define LCD_E         PIN_D0      // PIN 19 - LCD ENABLE
  60. #define LCD_RS          PIN_D1      // PIN 20 - LCD READ SELECT
  61. #define LCD_RW         PIN_D2      // PIN 21 - LCD READ - WRITE
  62. #define ClockZ         PIN_D3      // PIN 22 - SORTIDA RELLOTGE Z - VERD - 4
  63. #define LCD_DB4       PIN_D4      // PIN 27 - LCD BIT 4
  64. #define LCD_DB5         PIN_D5      // PIN 28 - LCD BIT 5
  65. #define LCD_DB6         PIN_D6      // PIN 29 - LCD BIT 6
  66. #define LCD_DB7         PIN_D7      // PIN 30 - LCD BIT 7
  67.  
  68. #define EnableX         PIN_E0      // PIN 08 - SORTIDA HABILITACIÓ X - LILA - 14
  69. #define EnableY         PIN_E1      // PIN 09 - SORTIDA HABILITACIÓ Y - MARRO - 16
  70. #define EnableZ         PIN_E2      // PIN 10 - SORTIDA HABILITACIÓ Z - GROC/NEGRE - 17


 

anything