Device: Lever - fdechaumont/micecraft GitHub Wiki

The lever is a device that the animals can press, with a LED on it.

  • This lever is very sensitive, it is very easy for the mice to press it.
  • Heavy duty: the mechanism is very simple, low friction and the sensor to detect the lever movement is a lidar
  • Runs with an Arduino Nano

[!NOTE] We tested this device with mice and rats.

  • Documentation
  • Examples
  • Blueprint
  • Manage Alarms
  • Auto-Reconnect

Events produced:

  • Lever press
  • Lever release
  • LightOn ( this event is returned when the user command a switch light On )
  • LightOff ( this event is returned when the user command a switch light Off )

Blueprints:

[!NOTE] Will be released on publication

Context Menu

Right click on the lever to get this menu.

[!TIP] You can use this menu to send event to your experiment program to test your code.

Example:

In this example, we create a lever, and we listen to its events.

from micecraft.devices.lever.Lever import Lever

if __name__ == '__main__':

    def myListener( event ):
        print( f"Event received:  {event}"  )
    
    lever = Lever( "COM24", "myLever" )
    lever.addDeviceListener( myListener )
    
    input("Press enter to stop the test")
    lever.shutdown()

Creating a simple user interface with a lever

This code creates

  • a box with 2 walls, 1 wall with a door access and 1 door with a grid.
  • a lever at the top of the room
# Definition of the visual elements
        
block = WBlock( 0,0 , self )
block.setName("Box")
block.addWall( Wall ( WallSide.RIGHT ) )
block.addWall( Wall ( WallSide.BOTTOM, wallType = WallType.GRID ) )
block.addWall( Wall ( WallSide.TOP ) )
block.addWall( Wall ( WallSide.LEFT, wallType = WallType.DOOR ) )
        
self.lever = Lever( "COM23" ) # Create a lever
visualLever = WLever( 0.25,-0.3, self ) # Create the visual lever widget
visualLever.setName("Lever")
visualLever.bindToLever( self.lever ) # Bind visual lever to device so that it can read its state.
        

Still, to run this piece of code, you need to setup it in a standalone QT app. Full code here:

import threading
import time
import traceback
import sys

from micecraft.devices.lever.Lever import Lever
from micecraft.soft.gui.Wall import Wall, WallSide, WallType
from micecraft.soft.gui.WLever import WLever
from micecraft.soft.gui.WBlock import WBlock
from PyQt6.QtWidgets import QWidget, QApplication
from PyQt6 import QtCore
from PyQt6.QtGui import QPainter, QPaintEvent


class WVisualExperiment(QWidget):
    
    refresher = QtCore.pyqtSignal()
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.shuttingDown = False
        
        print("Starting visual experiment...")
                
    def shutdown(self):
        
        print("Exiting...")
        self.shuttingDown = True
        self.lever.shutdown()
        print("Done.")
        
    
    def on_refresh_data(self):
        
        self.update()
    
    def monitorGUI(self):
        
        while( self.shuttingDown == False ):            
    
            self.refresher.emit()            
            time.sleep( 0.1 )      
            
    def listener(self , event ):
        print ( f"Event received: {event}" )
            
    def start(self ):
        
        # Definition of the visual elements
        
        block = WBlock( 0,0 , self )
        block.setName("Box")
        block.addWall( Wall ( WallSide.RIGHT ) )
        block.addWall( Wall ( WallSide.BOTTOM, wallType = WallType.GRID ) )
        block.addWall( Wall ( WallSide.TOP ) )
        block.addWall( Wall ( WallSide.LEFT, wallType = WallType.DOOR ) )
        
        self.lever = Lever( "COM23" ) # Create a lever
        visualLever = WLever( 0.25,-0.3, self ) # Create the visual lever widget
        visualLever.setName("Lever")
        visualLever.bindToLever( self.lever ) # Bind visual lever to device so that it can read its state.
        
        self.lever.addDeviceListener( self.listener )
        
        self.resize(400,400)
        self.setWindowTitle( "MiceCraft - Lever display test" )
                
        self.thread = threading.Thread( target=self.monitorGUI )
        self.refresher.connect(self.on_refresh_data)
        self.thread.start()
    
    def paintEvent(self, event: QPaintEvent):
                
        super().paintEvent( event )
        painter = QPainter()        
        painter.begin(self)
        # here should be located your custom display code
        
        painter.end()
    
def excepthook(type_, value, traceback_):
        traceback.print_exception(type_, value, traceback_)
        QtCore.qFatal('')

    
if __name__ == "__main__":
    
    sys.excepthook = excepthook
    
    def exitHandler():        
        visualExperiment.shutdown()
        
    
    app = QApplication([])
    
    app.aboutToQuit.connect(exitHandler)
    visualExperiment = WVisualExperiment()
    visualExperiment.start()
    visualExperiment.show()
        
    sys.exit( app.exec() )

This provides the following display:

Note that until you connect a lever, you will see a red dot blinking on the component complaining that there is no lever connected.

API

lightOn()
lightOff()
light(on:bool, pinNumber=11, pwm=255 )
isLightOn() -> bool
click()
"""Send click event"""