echiappe / BonsaiClub

Repository with materials for Chiappe Lab's Bonsai Club
0 stars 0 forks source link

Harp solution to synchronize setup #4

Open bruno-f-cruz opened 1 year ago

bruno-f-cruz commented 1 year ago

Current hardware streams include:

Suggested solution:

Add an Harp Behavior Board that acquires data from the photodiode (can be digital or analog at 1khz, it doesn't really matter) and simultaneously generates the two PWMs necessary to drive the cameras. Since we have timestamps for all these events given by the same microcontroller, we can easily align post-hoc.

Unfortunately, the behavior board does not natively support a DAC output to drive the galvo mirrors. It is possible to change part of the current-sourcing circuit responsible for driving the "LED" channel and turn it into a DAC. No idea about the temporal benchmarks of this solution, would need to perform some tests. However, since the high-speed camera would not go above 200hz, that would likely be the bottleneck of the closed loop system regardless.

Suggested circuit diagram:

image

miguel-paco commented 1 year ago

The 2 cameras we are using (for high and low resolution) are both the following model: UI-3360CP-NIR-GL Rev.2. They have a USB 3.0 micro-B that is used for power and we we are also using it to collect the video. It also has a 8-pin Hirose connector (HR25-7TR-8PA(73)), which I guess would be how you connect the cameras to the Harp Behaviour Board. Although I do not know how to do this, I will ask Artur about it.

Camera Model: https://en.ids-imaging.com/download-details/AB00624.html

High Res Framerate: 200.010000 Low Res Framerate: 85.000000

bruno-f-cruz commented 1 year ago

I dont have access to the documentation of these cameras. I can try to get a look at it if you can send me the pdfs to my email.

miguel-paco commented 1 year ago

I am looking into what would be our iDS account so I can have access to the documentation. Until then can you tell me what are you looking for specifically, maybe I can get that information another way.

bruno-f-cruz commented 1 year ago

I would need to know the input line to trigger frames, and the specs of the camera while in "Trigger mode". I am not even sure where that would be. But basically you want to figure out a way to trigger a frame on each rising edge from the camera.

miguel-paco commented 1 year ago

Galvo Mirror Pulse Pal Control Info

Pulse Pal v1.X

BaudRate = 115200; Voltage Range: byte 0:255 = -10V:+10V

Tell me if you need more information

Code controlling pulsepal:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Sardine.Core; using System.Threading; using System.IO.Ports; using FlyVRena2._0.ImageProcessing; using OpenCV.Net;

namespace FlyVRena2._0.External { public class PulsePal : Module where T : MovementData {

    public ManualResetEventSlim MREvent = new ManualResetEventSlim(false);
    public const int BaudRate = 115200; // Transfer Data rate 
    const int MaxDataBytes = 35; // Max Size of the Command Data

    SerialPort serialPort;
    bool initialized;
    byte[] readBuffer;
    byte[] responseBuffer;
    byte[] commandBuffer;

    // Pulse Pal Option Bytes For Data Transfer
    // 1st byte in command
    const byte OpMenu = 0xD5; // All commands should start with the Op menu byte 213
    // 2nd byte in command
    const byte HandshakeCommand = 0x48; // Option byte 72 ('H') - If Pulse Pal connected, it sends a byte 75 ('K') and firmware byte in response.
    const byte SetVoltageCommand = 0x4F; // Option byte 79 - Set a fixed voltage on an output channel
    const byte Acknowledge = 0x4B; // Option byte 75 (Program custom pulse train 1)

    public PulsePal(string portID)
    {
        // Serial Port Settings  - Pulse Pal v1.X (https://sites.google.com/site/pulsepalwiki/serial-interface)
        serialPort = new SerialPort(portID);
        serialPort.BaudRate = BaudRate; // Transfer Data rate 
        serialPort.DataBits = 8; // Transfer Data bit size
        serialPort.StopBits = StopBits.One; // Number of stop bits
        serialPort.Parity = Parity.None; // Method to detect errors
        serialPort.DtrEnable = false; // Data Terminal Ready
        serialPort.RtsEnable = true; //  Request to Send
        serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
        readBuffer = new byte[serialPort.ReadBufferSize];
        commandBuffer = new byte[MaxDataBytes]; // Max Size of the Command Data
        responseBuffer = new byte[4];
    }

    // Initialize Connection To Pulse Pal
    public void StartPulsePal()
    {
        serialPort.Open();
        serialPort.ReadExisting();
        commandBuffer[0] = OpMenu;
        commandBuffer[1] = HandshakeCommand;
        serialPort.Write(commandBuffer, 0, 2);
        this.Start();
    }

    protected override void Process(T data)
    {
        // Updates the voltage input into Pulsepal according to the tracking result
        Coordinates coord = new Coordinates() { PixelsCurve = new Point2d(data.position[0], data.position[1]) };

        if (data.ID != 0)
        {
            commandBuffer[0] = OpMenu; // Signal to pulsepal it will receive a command
            commandBuffer[1] = SetVoltageCommand; // command pulsepal to set a voltage value
            commandBuffer[2] = 1; // 1st Coordenate (X)
            commandBuffer[3] = (byte)Math.Round(coord.VoltageCurve.X); // Voltage Value
            if (commandBuffer[3] > 255) { commandBuffer[3] = 255; } else if (commandBuffer[3] < 0) { commandBuffer[3] = 0; } // Voltage can't be higher then 255 or lower then 0
            serialPort.Write(commandBuffer, 0, 4); // Send Command
            commandBuffer[2] = 2; // 2nd Coordenate (Y)
            commandBuffer[3] = (byte)Math.Round(coord.VoltageCurve.Y); // Voltage Value
            if (commandBuffer[3] > 255) { commandBuffer[3] = 255; } else if (commandBuffer[3] < 0) { commandBuffer[3] = 0; } // Voltage can't be higher then 255 or lower then 0
            serialPort.Write(commandBuffer, 0, 4); // Send Command
        }
        MREvent.Wait();
        MREvent.Reset();
    }

    void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        var bytesToRead = serialPort.BytesToRead;
        if (serialPort.IsOpen && bytesToRead > 0)
        {
            bytesToRead = serialPort.Read(readBuffer, 0, bytesToRead);
            for (int i = 0; i < bytesToRead; i++)
            {
                ProcessInput(readBuffer[i]);
            }
        }
    }

    void ProcessInput(byte inputData)
    {
        if (!initialized && inputData != Acknowledge)
        {
            throw new InvalidOperationException("Unexpected return value from PulsePal.");
        }
        switch (inputData)
        {
            case Acknowledge:
                initialized = true;
                break;
            default:
                break;
        }
    }

    public void OnExit()
    {
        this.Stop();
        serialPort.Close();
        serialPort.Dispose();
        MREvent.Dispose();
        this.Abort();
    }

    public void DisposeModule()
    {
        this.Dispose();
    }

}

}

miguel-paco commented 1 year ago

Relative to the camera, I do not know about the trigger. All I have is this photo of the trigger options on the camera user interface. Also, you should have access to the files in the website just by creating an account, you do not need to have it associated with the product.

20230224_162335

bruno-f-cruz commented 1 year ago

Mode = Rising edge and send a TTL pulse should produce frames, no?

miguel-paco commented 1 year ago

Right now we do not have the setup set to do that. I am not very knowledgeable on this subject, but I think we will need to order/get some cables to do that, or is the USB connection enough? If so, how can I set/test that? Is there someone I should talk to to help me with this?

bruno-f-cruz commented 1 year ago

Oh I thought you already had the hirose cables. Ye you might be able to connect a jumper wire directly if you just want to test it, but getting the cables is the best option. But yet keep me posted on the user manual and I will be able to provide more help.

On Fri, 24 Feb 2023 at 17:06, miguel-paco @.***> wrote:

Right now we do not have the setup set to do that. I am not very knowledgeable on this subject, but I think we will need to order/get some cables to do that, or is the USB connection enough? If so, how can I set/test that? Is there someone I should talk to to help me with this?

— Reply to this email directly, view it on GitHub https://github.com/neurogears/BonsaiClub/issues/4#issuecomment-1444043230, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABVZBB6WTBC4MBOUDW67FK3WZDTA3ANCNFSM6AAAAAAU4PX4YY . You are receiving this because you authored the thread.Message ID: @.***>