Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More pins for I/O #1

Open
reszelaz opened this issue Jun 8, 2018 · 7 comments · May be fixed by #10
Open

More pins for I/O #1

reszelaz opened this issue Jun 8, 2018 · 7 comments · May be fixed by #10

Comments

@reszelaz
Copy link
Contributor

reszelaz commented Jun 8, 2018

First of all many thanks for sharing this project! It will be very usefull for our needs (timed control of the pneumatic valves).

I was going to implement 5 more I/O pins. I was thinking about pins: 11, 12, 13, 15 and 16. Would you accept such PR?

@jensun84
Copy link
Contributor

Hi Zibi! I'd absolutely accept this PR. Yet, I have a task to add support for all GPIO pins. Maybe I can have it done within two weeks, I'll let you know.

Best, /J

@reszelaz
Copy link
Contributor Author

Do you think that the pin numbers are fine? If we agree on these we could already prepare the cabling in our setup.

@jensun84
Copy link
Contributor

Hi Zibi!
Yes, those numbers will work and are in the correct order. I will push by the end of today.
Best,
Jens

@jensun84
Copy link
Contributor

Hi Zibi!
In new commit:
*added support for 10 pins (3,5,7,8,10,11,12,13,15,16)
*removed socket timeout from tcp server
*removed hardcoded attribute polling
*for now, removed change event subscription and pushing

I have not had time to look at the tcp server causing the ~50ms overhead yet.
I did the changes quickly so please review the code before using. :)
All the best,/J

@AntoineDupre
Copy link
Member

AntoineDupre commented Jun 13, 2018

Hi,

Maybe you can consider setting the available pins through a tango property and then create pin attribute dynamically.

Dynamic attributes are created through initialize_dynamic_attributes function. This function is call after the init_device method.

Here a small example (not tested):

      pins = device_property(dtype=(int,)) 
                                                               
      def initialize_dynamic_attributes(self):                                     
          for pin_number in self.pins:                                             
              # Create attribute name                                              
              voltage_attrname = "pin{}_voltage".format(pin_number)                
              output_attrname = "pin{}_output".format(pin_number)                  
              # Get tango type                                                     
              tango_type = tango.CmdArgType.DevBoolean                             
              # Create attributes                                                  
              voltage_attr = tango.Attr(voltage_attrname,                          
                                        tango_type, tango.READ_WRITE)              
              output_attr = tango.Attr(output_attrname,                            
                                       tango_type, tango.READ_WRITE)               
              # Add attribute and setup read/write/allowed method                  
              self.add_attribute(                                                  
                  voltage_attr,                                                    
                  r_meth=self.read_pin_voltage,                                    
                  w_meth=self.write_pin_voltage,                                   
                  is_allo_meth=self.is_voltage_allowed)                            
              self.add_attribute(                                                  
                  output_attr,                                                     
                  r_meth=self.read_pin_output,                                     
                  w_meth=self.write_pin_output,                                    
                  is_allo_meth=self.is_output_allowed)                             
              # If event needed, setup change event                                
              self.set_change_event(voltage_attrname, True, True)                  
              self.set_change_event(output_attrname, True, True)                   
                                                                                   
      # Voltage                                                                    
                                                                                   
      @catch_connection_error                                                      
      def read_pin_voltage(self, attr):                                            
          attr_name = attr.get_name()                                              
          pin_number = int(filter(str.isdigit, attr_name))                         
          value = self.raspberry.readvoltage(pin_number)                           
          setattr(self, "__pin{}_voltage".format(pin_number), value)               
          attr.set_value(value)                                                    
                                                                                   
      @catch_connection_error                                                      
      def write_pin_voltage(self, attr):                                           
          w_value = attr.get_write_value()                                         
          attr_name = attr.get_name()                                              
          pin_number = int(filter(str.isdigit, attr_name))                         
          python_attr = "__pin_{}_voltage".format(pin_number)                      
          self.set_voltage(w_value, pin_number, getattr(self, python_attr))        
          setattr(self, "_{}".format(attr_name), w_value)                          
                                                                                   
      # Ouptut                                                                     
                                                                                   
      @catch_connection_error                                                      
      def read_pin_output(self, attr):                                             
          attr_name = attr.get_name()                                              
          pin_number = int(filter(str.isdigit, attr_name))                         
          value = self.raspberry.readoutput(pin_number)                            
          setattr(self, "__pin{}_output".format(pin_number), value)                
          attr.set_value(value)                                                    
                                                                                   
      @catch_connection_error                                                      
      def write_pin_output(self, attr):                                            
          w_value = attr.get_write_value()                                         
          attr_name = attr.get_name()                                              
          pin_number = int(filter(str.isdigit, attr_name))                         
          self.raspberry.setoutput(pin_number, w_value)                            
                                                                

You can notice that the write methods are slightly different. As attributes are created dynamically, you can not profit of the PyTango hight level API wrapping and you have to set yourself the attribute value (same to get the write value).

Cheers,
/Antoine

@reszelaz
Copy link
Contributor Author

Sounds good to me! For the moment we will try the recently added pins attributes which fulfills with our requirements. So do not rush with this refactoring just for us. Thanks a lot guys!

@jensun84
Copy link
Contributor

Thanks Antoine! The dynamic pin attributes is a great idea. I also realized that I can refactor the TCP IP server, adding an argument with argparse to flag wheter to start the HTTP server for the camera frame or not. In this case you’ll only add camera support to the server when needed.

cmft added a commit to cmft/dev-maxiv-raspberry_pi that referenced this issue Oct 11, 2021
Implement AntoineDupre proposal. Add  pin dev_property to set
the list of active pins

Fix MaxIV-KitsControls#1
@cmft cmft linked a pull request Oct 11, 2021 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants