Advertisement
Guest User

Untitled

a guest
Oct 17th, 2010
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.25 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # Written By kenkeiras <kenkeiras@gmail.com>
  4. # This program is free software. It comes without any warranty, to
  5. # the extent permitted by applicable law. You can redistribute it
  6. # and/or modify it under the terms of the Do What The Fuck You Want
  7. # To Public License, Version 2, as published by Sam Hocevar. See
  8. # http://sam.zoy.org/wtfpl/COPYING for more details.
  9.  
  10. import bluetooth, time, string
  11. from select import select
  12.  
  13. # Rellena los datos
  14. def padd(data, n, b = "\0"):
  15.     l = len(data)
  16.     while (l < n):
  17.         data.append(b)
  18.         l += 1
  19.     return data
  20.  
  21. # Rellena los datos en forma de stream
  22. def strpadd(data, n, b = "\0"):
  23.     l = len(data)
  24.     data = data + (b * (n - l))
  25.     return data
  26.  
  27. # Pasa un número de 3 bytes a str
  28. def uint24str(n):
  29.     data = []
  30.     data.append( chr(n & 255) )
  31.     n >>= 8
  32.  
  33.     data.append( chr(n & 255) )
  34.     n >>= 8
  35.  
  36.     data.append( chr(n & 255) )
  37.  
  38.     data.reverse() # Little endian
  39.  
  40.     return ''.join(data)
  41.  
  42.  
  43. # El controlador del mando
  44. class pymote:
  45.  
  46.     writing_port = 0x11  # Puerto L2CAP de envío de información
  47.  
  48.     reading_port = 0x13  # Puerto L2CAP de recepción de información
  49.  
  50.     max_packet_size = 36 # Tamaño máximo de un paquete
  51.  
  52.     # Prepara el byte del led
  53.     def get_led_byte(self):
  54.         b = 0
  55.         if (self.rumble):
  56.             b |= 1
  57.  
  58.         if (self.led[ 0 ] != 0):
  59.             b |= 0x10
  60.  
  61.         if (self.led[ 1 ] != 0):
  62.             b |= 0x20
  63.  
  64.         if (self.led[ 2 ] != 0):
  65.             b |= 0x40
  66.  
  67.         if (self.led[ 3 ] != 0):
  68.             b |= 0x80
  69.         return b
  70.  
  71.     # Ajusta los leds
  72.     def set_leds(self):
  73.         self.send(string.join([chr(0x52), chr(0x11),\
  74.                                     chr(self.get_led_byte()) ], ""))
  75.  
  76.  
  77.     # Activa/Desactiva los leds del mando
  78.     def toogle_led(self, d):
  79.         d = int(d)
  80.         self.led[d - 1] ^= 1
  81.         self.set_leds()
  82.         pass
  83.  
  84.     # Pregunta el estado del mando
  85.     def req_stat(self, d = None):
  86.         b = 0
  87.         if (self.rumble):
  88.             b |= 1
  89.  
  90.         self.send(string.join([chr(0x52), chr(0x15), chr(b)], ""))
  91.  
  92.     # Activa/desactiva la vibración
  93.     def toogle_rumble(self, d = None):
  94.         if (self.rumble):
  95.             self.rumble = False
  96.         else:
  97.             self.rumble = True
  98.         self.req_stat(d)
  99.  
  100.     # Activa/desactiva el speaker
  101.     def toogle_speaker(self, d = None):
  102.         b = 0
  103.         if (self.rumble):
  104.             b |= 1
  105.  
  106.         if (not self.speaker):
  107.             self.speaker = True
  108.             b |= 4
  109.             if (self.debug):
  110.                 print "Activado"
  111.         else:
  112.             self.speaker = False
  113.             if (self.debug):
  114.                 print "Desactivado"
  115.  
  116.         self.send(string.join([chr(0x52), chr(0x14), chr(b)], ""))
  117.         if (self.speaker):
  118.             time.sleep(0.1)
  119.             self.speaker_init()
  120.  
  121.     # Activa/desactiva la cámara IR
  122.     # Esto es algo más complicado, aún sin implementar
  123.     def toogle_ir(self, d = None):
  124.         b = 0
  125.         if (self.rumble):
  126.             b |= 1
  127.  
  128.         if (not self.ir):
  129.             self.ir = True
  130.             b |= 4
  131.             if (self.debug):
  132.                 print "Activado"
  133.         else:
  134.             self.ir = False
  135.             if (self.debug):
  136.                 print "Desactivado"
  137.  
  138.         self.send(string.join([chr(0x52), chr(0x13), chr(b)], ""))
  139.         time.sleep(0.1)
  140.         self.send(string.join([chr(0x52), chr(0x1a), chr(b)], ""))
  141.         time.sleep(0.1)
  142.  
  143.     # Escribe en un registro
  144.     def reg_write(self, pos, data):
  145.         b = 4
  146.         if (self.rumble):
  147.             b |= 1
  148.  
  149.         l = len(data)
  150.         if (l > 16):
  151.             raise Exception("Data too big =_=")
  152.         data = ''.join(padd(data, 16))
  153.         self.send(chr(0x52) + chr(0x16) + chr(b) + uint24str(pos) +
  154.                    chr(l) + data)
  155.  
  156.  
  157.     # Envia audio al mando
  158.     def send_audio(self, data):
  159.         l = len(data)
  160.         if (l > 20):
  161.             raise Exception("Data too big =_=")
  162.         self.send(chr(0x52) + chr(0x18) + chr(l << 3) + strpadd(data, 20))
  163.  
  164.     # Inicia el speaker
  165.     # Con un bus de 4 Bits ADPCM y un framerate de 3000Hz
  166.     def speaker_init(self):
  167.  
  168.         # Lo silencia
  169.         self.mute = False
  170.         self.toogle_mute()
  171.         time.sleep(0.1)
  172.  
  173.         # Escribe 1 en el registro 0xa20009
  174.         self.reg_write(0xa20009, [chr(0x01)])
  175.         time.sleep(0.1)
  176.  
  177.         # Escribe 8 en el registro 0xa20001
  178.         self.reg_write(0xa20001, [chr(0x08)])
  179.         time.sleep(0.1)
  180.  
  181.         # Se escoje la configuración (PCM 8 bits a 1500 Hz)
  182.         self.reg_write(0xa20001, [chr(0), chr(0x40), chr(0x40), chr(0x1F),\
  183.                                  chr(0x40), chr(0), chr(0)])
  184.         time.sleep(0.1)
  185.  
  186.         # Escribe 1 en el registro 0xa20008
  187.         self.reg_write(0xa20008, [chr(0x01)])
  188.         time.sleep(0.1)
  189.  
  190.         # Le devuelve el sonido
  191.         self.toogle_mute()
  192.  
  193.     # Silencia/Da voz al speaker
  194.     def toogle_mute(self, d = None):
  195.         b = 0
  196.         if (self.rumble):
  197.             b |= 1
  198.  
  199.         if (not self.mute):
  200.             self.mute = True
  201.             b |= 4
  202.             if (self.debug):
  203.                 print "Silenciado"
  204.         else:
  205.             self.mute = False
  206.             if (self.debug):
  207.                 print "Con voz"
  208.  
  209.         self.send(string.join([chr(0x52), chr(0x19), chr(b)], ""))
  210.  
  211.  
  212.     # Inicia el objeto y establece las conexiones
  213.     def __init__(self, baddr, name = None, debug = False, client = True):
  214.  
  215.         self.debug = False
  216.         self.led = [0, 1, 1, 0] # LED's
  217.         self.rumble = False     # Vibración
  218.         self.speaker = False    # Speaker
  219.         self.mute = False       # Speaker silenciado
  220.         self.ir = False         # Cámara IR
  221.         self.baddr = baddr      # Dirección bluetooth
  222.         self.name = None        # Nombre (no se usa)
  223.         if (client):
  224.             self.client_connect(baddr)
  225.         else:
  226.             self.server_connect(baddr)
  227.  
  228.         self.toogle_speaker()
  229.  
  230.     # Recibe el siguiente paquete de información
  231.     def get_next(self):
  232.  
  233.         data = None
  234.         (r, w, e) = select([self.r_s, self.w_s], [], [])
  235.         if (self.r_s in r):
  236.             data = self.r_s.recv(self.max_packet_size )
  237.             if (len(data) < 1):
  238.                 self.connected = False
  239.  
  240.         elif (self.w_s in r):
  241.             data = self.w_s.recv(self.max_packet_size )
  242.             if (len(data) < 1):
  243.                 self.connected = False
  244.  
  245.         else:
  246.             self.connected = False
  247.  
  248.         return data
  249.  
  250.     # Establece las conexiones directamente
  251.     def client_connect(self, baddr):
  252.         try:
  253.  
  254.             # Socket de escritura, envía información
  255.             self.w_s = bluetooth.BluetoothSocket( bluetooth.L2CAP )
  256.             self.w_s.connect((baddr, self.writing_port))
  257.  
  258.             # Socket de lectura, recibe información
  259.             self.r_s = bluetooth.BluetoothSocket( bluetooth.L2CAP )
  260.             self.r_s.connect((baddr, self.reading_port))
  261.  
  262.             self.connected = True
  263.  
  264.         except:
  265.             raise Exception("Fallo al conectar")
  266.  
  267.     # Acepta conexiones nuevas
  268.     def server_connect(self, baddr):
  269.         try:
  270.  
  271.             # Socket de escritura, envía información
  272.             self.w_s = bluetooth.BluetoothSocket( bluetooth.L2CAP )
  273.             self.w_s.bind(("", self.writing_port))
  274.             self.w_s.listen(1)
  275.             (self.w_s, self.baddr) = self.w_s.accept()
  276.  
  277.             # Socket de escritura, envía información
  278.             self.r_s = bluetooth.BluetoothSocket( bluetooth.L2CAP )
  279.             self.r_s.bind(("", self.reading_port))
  280.             self.r_s.listen(1)
  281.             (self.r_s, self.baddr) = self.r_s.accept()
  282.  
  283.             self.connected = True
  284.  
  285.         except:
  286.             raise Exception("¿Seguro que puedes abrir un puerto? ¬¬")
  287.  
  288.     # Envía algo
  289.     def send(self, data):
  290.         l = len(data)
  291.         c = 0
  292.         while (c < l):
  293.             c += self.w_s.send(data[ c : ])
  294.  
  295.     # Cierra las conexiones
  296.     def close(self):
  297.         self.w_s.close()
  298.         self.r_s.close()
  299.  
  300.     # Comprueba si está conectado
  301.     def is_connected(self):
  302.         return self.connected
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement