Autor Tema: pic reloj  (Leído 16411 veces)

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

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:pic reloj
« Respuesta #30 en: 13 de Octubre de 2016, 23:11:02 »
Mi consejo nuevamente... Empeza a debuggear o aprende a valerte con las herramientas que tenes.

Tenes un LCD, tenes un simulador!

Podes simular paso a paso para ver si lo que llega es correcto! Veamos algunos pasos que podes hacer:

1 - Asegurarte de lo que llega, es decir el contenido de los registros RXlsb y RXmsb sea lo correcto. ( Si falla es problema la subrutina de "read" o el inicio del sensor )
2 - Si es correcto lo anterior, verificar que lo que sale de la rutina CalcRH, es decir verificar que el valor de RH sea correcto segun lo que llego (Si no lo es, esta fallando CalcRH)
3 - ????
4 - Profit

Hay cosas que no me gustan de tu programa, por ejemplo al comienzo pones las conexciones SCLK y SDA como salidas y en 0, luego estas asi por 5 veces RETA980 que si no entiendo mal en tus comentarios dice 980.000us, eso es 0.98s cada uno!!!. Seguro hay un error en el comentario ( quiero imaginar ). En fin, lo tenes en 0, podrias haberlo iniciado como entrada al SDA de esa forma solo se iba a 1 por la resistencia de Pull-up.

Seguimos con los delays, Tenes como 5 de esos en el LCD nomas! 5!!!! cuando tal ves necesitas 200ms como maximo una sola ves. Pero encima luego le das otro RETA980 mas para esperar los 11ms del sensor, los cual ya paso gracias a todo lo del LCD y no necesitas ese retardo...

Como te decia, debugea paso a paso, No podes hacerlo ? entonces crea una rutina que muestre en el LCD los valores de RXmsb y RXlsb, y luego tambien RH.

La idea es ir separando el problema poco a poco hasta encontrar el culpable o punto donde esta fallando. Pensalo como que cortas a la mitad el programa, y decis "¿Hasta aca funciona?" Si es SI entonces tenes una mitad buena y la otra mala, si es NO, vas a tener que volver a dividir esa mitad mala y volver a aplicar todo el proceso.

Desconectado juansanchezruiz05

  • PIC10
  • *
  • Mensajes: 30
Re:pic reloj
« Respuesta #31 en: 14 de Octubre de 2016, 06:03:11 »
Ir comprobando el programa por partes es lo que he ido haciendo, por eso se que me funciona todo el programa menos las rutinas del Sht11. Creo que la única rutina que no me funciona es la de leer la medida. Si empre se carga el el registro RXlsb el mismo valor.

La LCD funciona correctamente, es verdad que hay muchos retardos, pero por exceso de tiempo no deja de funcionar ira mas lento pero funciona.

Si me pudieraís decir si la rutina de leer la tengo bien o mal, porque creo que ahí esta el problema.
« Última modificación: 14 de Octubre de 2016, 07:49:16 por juansanchezruiz05 »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:pic reloj
« Respuesta #32 en: 14 de Octubre de 2016, 08:33:35 »
Si me pudieraís decir si la rutina de leer la tengo bien o mal, porque creo que ahí esta el problema.

Y es exactamente donde te estoy pidiendo que veas en tu simulador el porque esta fallando. Ya encontraste el DONDE, ahora necesitas el POR QUE. Vas por buen camino.

Mal comando?
Mal inicio de pedido?
Malos tiempos? ( podes agregar un par de nops, si nada cambia eso no es el error)

Considero que que deberias poner DATA a 1 al comienzo del programa y no despues del LCD.

Mirando el codigo y algunas cosas que no me gustan pero:

Código: ASM
  1. cont_send       rlf     CMData,F        ;rota a la izquierda, bit alto en carry
  2.                 btfsc   CMData,7        ;comprueba si es 1 o 0
  3.                 goto    uno             ;

Pienso que es un error y lo que quisieron hacer es:

Código: ASM
  1. cont_send       rlf     CMData, F       ;rota a la izquierda, bit alto en carry
  2.                 btfsc   STATUS, C       ;comprueba si es 1 o 0
  3.                 goto    uno             ;

Sino se estaria perdiendo el bit 7 en el proceso.
« Última modificación: 14 de Octubre de 2016, 09:02:09 por KILLERJC »

Desconectado juansanchezruiz05

  • PIC10
  • *
  • Mensajes: 30
Re:pic reloj
« Respuesta #33 en: 14 de Octubre de 2016, 09:08:39 »
Gracias. He hecho las correcciones y recomendaciones que me has dicho. Pero ahí no está el problema, ya que lo he vuelto a simular y nada siempre se carga el mismo valor en RXlsm y en el otro. Además la rutina de mandar comando estaba bien y ahora con las mejoras también, porque proteus no envia mensajes de el comando que ha llegado al sht11 está reservado o no se puede implementar.

Si me puedes hacer el favor de mirar la rutina de lee valor, te lo agradecería. Porque esa parte en el datasheet no la entendía muy bien, y en las rutinas que he mirado de internet después de leer el byte alto, vuelve sincronizar justo antes de leer el byte bajo. En el datasheet no dice nada de esto último.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:pic reloj
« Respuesta #34 en: 14 de Octubre de 2016, 10:28:50 »
No se a que llamas sincronizar, si te referis al ACK, este es un aviso de que llego correctamente el dato. Y se debe enviar cada 8bits

Es decir:

- Envio de Comienzo de Transimision
- Envio de Comando(8 bits)
- Esperar ACK
- Espera que este completo el dato
- Recepcion de los 8 bits
- Enviar ACK
- Recepcion de los otros 8 bits
- Decidir, Si se envia el ACK significa que se quiere recibir el checksum, si no se envia (DATA = 1 y un pulso de clock, NACK) se omite el envio de checksum
- Recepcion de checksum en caso de usarlo.
- Enviar ACK (NACK) luego de recibir el checksum

Citar
Gracias. He hecho las correcciones y recomendaciones que me has dicho. Pero ahí no está el problema, ya que lo he vuelto a simular y nada siempre se carga el mismo valor en RXlsm y en el otro

Ese es mi problema, estas diciendo que esta bien, pero ahi influye eso. Nuevamente te estoy pidiendo que simules paso a paso, y veas en un osciloscopio o un analizador logico que las señales sean las correctas. No se como estas simulando. Por que solo me estas diciendo los resultados finales que es cuando tenes el resultado en RXxsb. Y no si los datos que salen del SHT11 son los correctos, ademas lo peor de todo es que estamos hablando de una simulacion.

El  SHT11 esta dando el mismo valor con distintas humedades?
Es problema del PIC que esta leyendo o esta enviando mal los pulsos de clock?

Por si no se entiende, lo que estoy diciendo es que compares la Figura 17, Pagina 7 del datasheet del SHT11 con respecto a lo que tenes vos en la simulacion, usa el valor 35.5% de valor de humedad relativa en Proteus y deberias tener aproximadamente el mismo resultado.

Te dejo nuevamente el datasheet del SHT11
https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/Humidity_Sensors/Sensirion_Humidity_Sensors_SHT1x_Datasheet_V5.pdf

Te estoy intentando hacer valor la informacion que tenes, la resolucion de problemas es asi, es acortar el mismo hasta encontrarlo, sabemos que recibe lo mismo siempre, pero POR QUE? Eso es lo que intentamos averiguar, el SHT11 envia correctamente los datos? o es culpa del PIC?, el programa parece correcto, seran los tiempos ? (probalo a 1Mhz y si sigue sin funcionar entonces no es eso).
El PIC esta enviando las cosas como debe y se me esta escapando algo del programa? Tengo un grafico para comparar, genial, puedo agarrarme de eso y revisar que ambos sean iguales!.

No te estoy dando la solucion, te estoy dando una idea para que lo soluciones y encontres por vos mismo, que es mucho mas util que darte una libreria funcional.

PD: No uso Proteus.

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1297
Re:pic reloj
« Respuesta #35 en: 14 de Octubre de 2016, 14:26:17 »
He encontrado algunos detalles en las rutinas.

Primero comenzare con la subrutina de SHT11_CMD. Actualmente tienes esto:

SHT11_CMD   movwf   CMData      ;guarda el comando en variable
   
      bsf   STATUS,5   ;banco 1
      bcf   TRISA,2      ;puertos como salida
      bcf   TRISA,1

      bcf   STATUS,5   ;banco 0
      bSf   PORTA,1      ;DATA a 1 (por defecto)
      bCf   PORTA,2      ;CLK

      nop         ;espera un poco
      nop

      bsf   PORTA,2      ;CLK
      bcf   PORTA,1      ;DATA   (pulso bajo)
      bcf   PORTA,2      ;CLK
      nop
      bsf   PORTA,2      ;CLK
      bsf   PORTA,1      ;DATA (por defecto alto)
      bcf   PORTA,2      ;CLK
                nop
                bsf   PORTA,2           ;CLK

La instruccion en color naranja la puedes omitir si desde la configuracion del micro la defines como salida, ya que el pin de CLK siempre es salida, nunca cambia.
Las instrucciones en amarillo pueden ser cambiadas para que la linea de CLK este en alto.
La instruccion en rojo definitivamente esta mal ya que eso genera un pulso de CLK extra generando una equivodada secuencia de inicio. LEER LA HOJA DE DATOS.

Mi sugerencia para la rutina seria asi:

SHT11_CMD   movwf   CMData      ;guarda el comando en variable
   
      bsf   STATUS,5   ;banco 1
      bcf   TRISA,2      ;puertos como salida. No es necesaria si se declara el puerto como salida desde la configuracion inicial del micro
      bcf   TRISA,1

      bcf   STATUS,5   ;banco 0
      bSf   PORTA,1      ;DATA a 1 (por defecto)
      bsf   PORTA,2      ;CLK

      nop         ;espera un poco
      nop
      
      bcf   PORTA,1      ;DATA   (pulso bajo)
                nop    ;NOP agregado
      bcf   PORTA,2      ;CLK
      nop
      bsf   PORTA,2      ;CLK
      bsf   PORTA,1      ;DATA (por defecto alto)
                nop
      bcf   PORTA,2      ;CLK

Veamos la siguiente parte de esta misma subrutina. Actuamente tienes:

                clrf   sincbit
      bcf   STATUS,C   ;borra carry
      bsf   STATUS,5   ;banco 1
      bcf   TRISA,1      ;pone DATA port,0 como salida
      bcf   STATUS,5   ;banco 0


                bcf    STATUS,5 ;banco 0

      movlw    0x00
      MOVWF   sincbit


      
cont_send   rlf   CMData,F   ;rota a la izquierda, bit alto en carry

               ;envio de datos segun el protocolo del sht11
send_data   btfsc   CMData,7   ;comprueba si es 1 o 0
      goto   uno      ;

cero      bcf   PORTA,2      ;SCK  falling edge -_
      bcf   PORTA,1      ;DATA change
      bsf   PORTA,2      ;SCK  rising edge  _-
      goto   sht11_compTX   ;salta

uno      bcf   PORTA,2      ;SCK  falling edge -_
      bsf   PORTA,1      ;DATA change
      bsf   PORTA,2      ;SCK  rising edge  _-

;Comprobacion para 8 rotaciones, una por bit del comando.
sht11_compTX    movlw    0x07      ;comprobacion 8 bits
                subwf   sincbit,W       ;Compara
                btfsc   STATUS,Z        ;Es el ultimo?             
                return         ;Si,
                incf    sincbit,f       ;Incrementa numero de sincbit
                goto    cont_send   ;Vuelve a escribir

Las primeras lineas en naranja no son necesarias ya que el pin de DATA ya esta configurado como salida.
La siguiente linea en rojo esta demas.
Las siguientes lineas en naranja estan demas, ya que previamente has usado un clrf.
La siguiente linea en rojo esta mal, deberias preguntar por el carry con un btfsc STATUS,C (que esto ya te lo comento KILLERJC)
La siguiente linea roja esta mal, deberia ser un 8 en lugar de un 7.

Entonces con estos cambios deberia quedar así:

                clrf   sincbit
      bcf   STATUS,C   ;borra carry
      
cont_send   rlf   CMData,F   ;rota a la izquierda, bit alto en carry

               ;envio de datos segun el protocolo del sht11
send_data   btfsc   STATUS,C   ;comprueba si es 1 o 0
      goto   uno      ;

cero      bcf   PORTA,2      ;SCK  falling edge -_
      bcf   PORTA,1      ;DATA change
      bsf   PORTA,2      ;SCK  rising edge  _-
      goto   sht11_compTX   ;salta

uno      bcf   PORTA,2      ;SCK  falling edge -_
      bsf   PORTA,1      ;DATA change
      bsf   PORTA,2      ;SCK  rising edge  _-

;Comprobacion para 8 rotaciones, una por bit del comando.
sht11_compTX    movlw    0x08      ;comprobacion 8 bits
                subwf   sincbit,W       ;Compara
                btfsc   STATUS,Z        ;Es el ultimo?             
                return         ;Si,
                incf    sincbit,f       ;Incrementa numero de sincbit
                goto    cont_send   ;Vuelve a escribir

Continuemos con la rutina de waitACK. Aquie hay un problema de ciclo, ya que si por alguna razon el sensor no enviara el ACK, entonces continuamente estas enviando pulsos de CLK hasta que llegue el ACK. Esto es incorrecto, si no llega el ACK entonces sales de la rutina y levanta una bandera o usa un valor para indicar que hubo un error.

Tu subrutina es esta:
;---------------- Espera la llegada de ACK desde el sensor -----------------
waitACK      bsf   STATUS,5   ;banco 1
      bsf   TRISA,1      ;pone DATA port,0 como entrada
      bcf   STATUS,5   ;banco 0   
      
ACKrx      bcf   PORTA,2      ;SCK  falling edge
      bsf   PORTA,2      ;SCK  rising edge
      btfsc   PORTA,1      ;comprueba data
      goto   ACKrx      ;NO, bucle
      bcf   PORTA,2      ;SCK  falling edge estado bajo por defecto
      return


Mi recomendacion es:

;---------------- Espera la llegada de ACK desde el sensor -----------------
waitACK      bsf   STATUS,5   ;banco 1
      bsf   TRISA,1      ;pone DATA port,0 como entrada
      bcf   STATUS,5   ;banco 0
      
ACKrx   bcf   PORTA,2      ;SCK  falling edge
      nop
      bsf   PORTA,2      ;SCK  rising edge
      btfsc   PORTA,1      ;comprueba data
      retlw .1              ;Sal de la subrutina con w=1, indicando que se genero un error
      bcf   PORTA,2      ;SCK  falling edge estado bajo por defecto
                clrw                          ;w=0 indicando que se recibio correctamente el ACK del sensor
      return


Ahora vamos con ela rutina de recepcion de datos (read). La pondre por secciones:

read         btfsc   PORTA,1
         goto   read


Estas dos intrucciones no son necesarias, ya que antes de ejecutar la subrutina read, ejecutas la subrutina de adqtime. Pero no afectan la operacion, las puedes dejar o quitar.

Ayer te mencionaba que un detalle estaba en la recepcion del low_byte en esta rutina, ya que despues de recibir el RXlsb envias un ACK al sensor, eso le dice al sensor que proceda a enviar el checksum, pero no tienes esta parte de la rutina, asi que lo correcto es enviar un NACK, diciendo al sensor que para de eviar datos. Es decir, tu tienes esto:

low_byte           rlf   RXmsb,F
         bcf   RXmsb,0
         bsf   PORTA,2
         btfsc   PORTA,1
         bsf   RXlsb,0

         bcf   PORTA,2

         decfsz   sincbit,F
         goto   low_byte

         bsf   STATUS,5      ; register page 1
         bcf   TRISA,1         ; SHT11_DATA es salida
         bcf   STATUS,5      ; register page 0

         bcf   PORTA,1
         nop
         bsf   PORTA,2
         nop
         bcf   PORTA,2
   
         bsf   STATUS,5      ; register page 1
         bsf   TRISA,1         ; SHT11_DATA es entrada
         bcf   STATUS,5      ; register page 0

         return

La primera instruccion en rojo esta equivocada, esta deberia ser: bsf RXmsb,0
La segunda instruccion en rojo deberia ser: bsf PORTA,1. Este es el NACK, y tu tienes un bcf y eso es un ACK. Esto solo aplica en el low_byte, el high_byte esta corrrecta, ahi si necesitas un ACK.

El codigo seria:

low_byte           rlf   RXmsb,F
         bcf   RXmsb,0
         bsf   PORTA,2
         btfsc   PORTA,1
         bsf   Rmlsb,0

         bcf   PORTA,2

         decfsz   sincbit,F
         goto   low_byte

         bsf   STATUS,5      ; register page 1
         bcf   TRISA,1         ; SHT11_DATA es salida
         bcf   STATUS,5      ; register page 0

         bsf   PORTA,1
         nop
         bsf   PORTA,2
         nop
         bcf   PORTA,2
   
         bsf   STATUS,5      ; register page 1
         bsf   TRISA,1         ; SHT11_DATA es entrada
         bcf   STATUS,5      ; register page 0

         return

No he verificado si los cambios funcionan, pero tu los puedes simular paso a paso. Tal vez necesites agregar mas NOP para hacer que la frecuencia del CLK sea mas baja, ya que la frecuencia para el sensor esta limitada a 1MHz para voltajes de alimentacion menores a 4.5V y a 5MHz para voltajes mayores s 4.5V. Mi recomendacion es que uses una frecuencia del pin de CLK de 1MHz o menos.

Espero esto te sirva,

elreypic.
« Última modificación: 14 de Octubre de 2016, 14:32:46 por elreypic2 »

Desconectado juansanchezruiz05

  • PIC10
  • *
  • Mensajes: 30
Re:pic reloj
« Respuesta #36 en: 14 de Octubre de 2016, 15:25:01 »
Muchas gracias. he hecho las correcciones que me has indicado y sigue mostrándome el mismo valor siempre por la LCD.

Solo tengo el ordenador para comprobar el código, concretamente solo proteus. Por ese motivo primero programe la LCD y el conversor de binario a Ascii, verifique que funcionaba correctamente y que mostraba los valores bien, de esta forma podía comprobar que el sht11 funcionaba o no.

Creo que lo mejor sería que me pasarais una librería para este sensor, que este comprobada de que funciona correctamente con un circuito real, si podéis y no es mucha molestia, y que luego yo la comparase con la mía hasta que diera con los errores. Después publicaría mis errores en un mensaje para que vierais que no la he copiado y pegado.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:pic reloj
« Respuesta #37 en: 14 de Octubre de 2016, 16:04:38 »
Citar
Creo que lo mejor sería que me pasarais una librería para este sensor, que este comprobada de que funciona correctamente con un circuito real

¿ No crees que ese es tu trabajo ?

Yo te dije que tenes que hacer... con el ordenador lo podes hacer. Incluso en el MPLAB (IDE con el cual estarias programando esto) podes simularlo paso a paso y ver que las señales que salen sean correctas. Es decir tenes 2 simuladores funcionando al frente tuyo. Es hora de usarlos.

Se que es frustante que algo no funcione, pero tenes que aprender a resolver problemas con lo que tenes, y tenes MUCHO, porque muchas veces no tenes un "Proteus" que te pueda salvar como en este caso. Un ejemplo seria, como harias con un sensor que no se encuentra en la libreria de Proteus y lo que bajaste no funciona?
« Última modificación: 14 de Octubre de 2016, 16:23:02 por KILLERJC »

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1297
Re:pic reloj
« Respuesta #38 en: 14 de Octubre de 2016, 16:31:56 »
Podrias colocar imagenes de los datos que obtienes despues de la lectura del sensor.
Como dice KILLERJC, tienes que simularlo paso a paso. Haz lo siguiente en tu codigo:
Realiza una lectura del sensor sin llamar la rutina que calcula el %RH y ajusta la linealidad, es decir no llames la rutina CalcRH y muestra los valores de RXlsb y de RXmsb en la LCD.
Estos son los que interesan para ver si estan bien o no.

Elreypic.

Desconectado juansanchezruiz05

  • PIC10
  • *
  • Mensajes: 30
Re:pic reloj
« Respuesta #39 en: 14 de Octubre de 2016, 16:55:36 »
eso ya lo he hecho siempre muestra el mismo. Creo que siempre muestra 0.

si tienes una rutina que funcione pasamela y la comparo con la mía hasta que lo saque. Porque ya no se donde puede estar el fallo.
a lo mejor es el programa proteus, pero es que no tengo otro.
« Última modificación: 14 de Octubre de 2016, 17:00:40 por juansanchezruiz05 »

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1297
Re:pic reloj
« Respuesta #40 en: 14 de Octubre de 2016, 17:06:15 »
juansanchezruiz05,

No tengo una rutina que funcione, ya que nunca he usado este sensor. POr eso te pido que coloques unas imagenes y ademas pon el codigo que haces para realizar la lectura de la temperatura antes de convertirla. Dices que ya lo hiciste, OK, hazla de nuevo y muestrame los resultados.

elreypic.

Desconectado juansanchezruiz05

  • PIC10
  • *
  • Mensajes: 30
Re:pic reloj
« Respuesta #41 en: 14 de Octubre de 2016, 17:13:06 »
No se como mostrartelo. Así te valdría??
Solo estoy intentando que me lea la humedad.

Rutina para medir la humedad:

sht11_Humedad   movlw   b'00000101'
      call   SHT11_CMD   ;Envio: Lectura de humedad
      call   waitACK      ;espera que llegue ACK desde el sensor
      call   adqtime      ;espera que pase el tiempo de adquisicion
      BCF   STATUS,5
      bsf   PORTA,1
      call   read
      call   CalcRH      ;Calcula %RH y ajusta linealidad
               ;retorna variable RH COMO dato      
      return
« Última modificación: 14 de Octubre de 2016, 17:16:48 por juansanchezruiz05 »

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1297
Re:pic reloj
« Respuesta #42 en: 14 de Octubre de 2016, 17:27:28 »
Esto me muestra que no entiendes lo que se te pide o que simplemente no quieres hacerlo. Y aunque dices que ya lo has hecho, esto me muestra que no lo has hecho.
Lo que me estas mostrando es el valor de la humedad ya convertida, yo no te pedi eso. Claramente te dije que despues de que realices la lectura de los datos (12bits) del valor de la humedad entregada por el sensor, los muestres en la LCD. No quiero el valor convertido, quiero el valor en digital de la humedad, es decir quiero que muestres los valores que contienen las variables RXlsb y RXmsb.

sht11_Humedad   movlw   b'00000101'
      call   SHT11_CMD   ;Envio: Lectura de humedad
      call   waitACK      ;espera que llegue ACK desde el sensor
      call   adqtime      ;espera que pase el tiempo de adquisicion
      BCF   STATUS,5
      bsf   PORTA,1
      call   read
hasta aqui has leido, aqui es donde quiero que conviertas los datos ue contienen las variables RXlsb y RXmsb a ASCII y los muestres en la LCD. Eso es lo que quiero ver.

elreypic.

Desconectado juansanchezruiz05

  • PIC10
  • *
  • Mensajes: 30
Re:pic reloj
« Respuesta #43 en: 14 de Octubre de 2016, 19:34:53 »
Ok

Esto es, no??

El error debe estar en la rutina de leer medida, porque los comandos se mandan correctamente, sino proteus indicaría lo contrario.
« Última modificación: 14 de Octubre de 2016, 19:58:20 por juansanchezruiz05 »

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1297
Re:pic reloj
« Respuesta #44 en: 14 de Octubre de 2016, 20:20:39 »
No encuentro en el codigo la parte en que haces la conversion de la lectura digital del sensor a ASCII.
No se que significa eso se muestra.

Podrias indicarme en donde lo hiciste?

elreypic.

P.S Tu codigo tal como esta tiene un error y no ensambla. Como es que estas haciendo tus pruebas?
« Última modificación: 14 de Octubre de 2016, 20:48:36 por elreypic2 »