Jump to content
maurosmartins

DLL que depende de outra DLL

Recommended Posts

maurosmartins

Viva pessoal,

Para um projecto recente estou a usar um chip que converte de USB para SPI (MCP2210) que por sua vez irá controlar um módulo de comunicações sem fios (NRF24L01+).

O conversor MCP2210 é fornecido com um DLL que permite enviar e receber os dados por SPI bem como controlar alguns pinos de utilização genérica (GPIO).

Agora gostaria de criar em cima disto outra DLL que contenha as funções para controlar o NRF24L01+ e que utiliza as funções continas na DLL do MCP2210.

Estou a usar C#, podem dar-me algumas indicações de como proceder para obter este resultado?

Cumprimentos, Mauro.

Share this post


Link to post
Share on other sites
kalin

Se estiveres a utilizar o visual studio, podes criar um novo projecto, para uma dll o template "Class Library".

Para referênciar a dll que queres utilizar, basta clicar com o botão direito do rato sobre as References do project e podes fazer browse para a dll.

Quando terminares, deves fazer um build ao projecto e verificar se existem erros, deves abrir as references e verificar se existe algum sinal de aviso, podes ter que alterar a versão do .net para ser equivalente a da dll que estás a referenciar.

Deves verificar ainda que nas propriedades da referencia a dll que adicionaste, a propriedade "Copy Local" está a true, isto porque a dll que criaste deve ter uma cópia da dll que estás a referênciar na mesma pasta, caso contrário vais ter excepções ao excecutar a tua dll.

Share this post


Link to post
Share on other sites
maurosmartins

Olá a todos,

@kalin, muito obrigado pela resposta detalhada!

Tenho mais algumas questões a colocar,

para aceder ao MCP2210 tenho de instanciar um objecto do tipo DevIO, como proceder para que na nova DLL só o tenha de fazer uma vez, ou seja ser global ao programa?

isto porque no programa final gostaria que fosse qq coisa do género:

using System;
using usb2nrf24l01p;
namespace programa
{
class Program
{
 public static void Main(string[] args)
 {
				 string resposta;
				 nrf24l01p nrf=new nrf24l01p();
				 nrf.init();
				 nrf.send("texto");
				 resposta=nrf.receive();
				 console.write(resposta);

 }
}
}

Este é um exemplo (resumido) do que quero conseguir fazer.

Cumprimentos, Mauro.

Share this post


Link to post
Share on other sites
kalin

Para teres uma variável "global" podes usar uma variável auxiliar privada que guarde o estado da propriedade que queres que seja global, ou seja:

public class GlobalProperties
{
private DevIO device;
public DevIO Device
{
	get { return device ?? new DevIO(); }
	set { device = value; }
}
}

Isto é o mais simples, o problema é que se precisares de aceder a esta propriedade em vários sítios diferentes, vais instanciar várias vezes a classe GlobalProperties e o teu problema mantém-se, para resolver isto precisa que esta classe seja um Singleton, ou seja:


public class GlobalProperties
{
private static volatile GlobalProperties instance;
private static object syncRoot = new Object();

private GlobalProperties() { }

public static GlobalProperties Instance
{
	get
	{
		if (instance == null)
		{
			lock (syncRoot)
			{
				if (instance == null)
					instance = new GlobalProperties();
			}
		}

		return instance;
	}
}

private DevIO device;
public DevIO Device
{
	get { return device ?? new DevIO(); }
	set { device = value; }
}
}

Podes ver mais informações sobre singletons aqui

Share this post


Link to post
Share on other sites
maurosmartins

Olá pessoal,

Kalin, obrigado pela resposta!

o meu código de momento está assim (dividido em dois ficheiros/classes):

using System;
using Usb2Nrf;
namespace usbspi{
class Program{

 public static void Main(string[] args)
 {
  byte StatusReg;
  byte [] payload =new Byte[10];

  nrf24l01p nrf = new nrf24l01p();



  //nrf.DefaultTx();

  nrf.DefaultRx();
  while (true) {

StatusReg=nrf.ReadStatusRegister();
//Console.Write(StatusReg.ToString()+"\n");


if((StatusReg&0x40)!=0x00){

 nrf.RxData(payload);

 Console.Write("{0}, {1}, {2}, {3}\n",payload[1],payload[2],payload[3],payload[4]);

}

System.Threading.Thread.Sleep(100);


  }


//
//   for (int i = 0; i < 100000; i++) {
//
//
//	nrf.TxData();
//
//	//nrf.tdata();
//
//	System.Threading.Thread.Sleep(1000);
//
//	Console.Write("ite {0}\n",i);
//	Console.Write("status register = {0}\n",(nrf.ReadRegister(0x00)).ToString("x"));
//
//   }


 }
}
}

e:

using System;
using MCP2210;
namespace Usb2Nrf{


class nrf24l01p{

 private const uint MCP2210_VID = 0x04D8;   // VID for Microchip Technology Inc.
 private const uint MCP2210_PID = 0x00DE;   // PID for MCP2210
 private MCP2210.DevIO UsbSpi;


 public byte ReadStatusRegister(){
  byte[] datatx = new Byte[1];
  byte[] datarx = new Byte[1];

  UsbSpi.Settings.SetSpiTxferSize(MCP2210.DllConstants.CURRENT_SETTINGS_ONLY,1); //so transfere 1 byte de cada vez
  UsbSpi.Functions.TxferSpiData(datatx,datarx); //ler
  return datarx[0];
 }

 public byte ReadRegister(byte register){

  byte[] datatx = new Byte[2];
  byte[] datarx = new Byte[2];

  UsbSpi.Settings.SetSpiTxferSize(MCP2210.DllConstants.CURRENT_SETTINGS_ONLY,2);
  datatx[0]=register;
  datatx[1]=register;  //dummy
  UsbSpi.Functions.TxferSpiData(datatx,datarx);

  return datarx[1];
 }

 public void FlushTxFifo(){
  byte[] datatx = new Byte[1];
  byte[] datarx = new Byte[1];

  UsbSpi.Settings.SetSpiTxferSize(MCP2210.DllConstants.CURRENT_SETTINGS_ONLY,1);
  datatx[0]=0xE1;
  UsbSpi.Functions.TxferSpiData(datatx,datarx);
 }

 public void WriteRegister(byte register,byte value){
  byte[] datatx = new Byte[2];
  byte[] datarx = new Byte[2];

  UsbSpi.Settings.SetSpiTxferSize(MCP2210.DllConstants.CURRENT_SETTINGS_ONLY,2);
  datatx[0]=(byte)((0x20)|register);
  datatx[1]=value;
  UsbSpi.Functions.TxferSpiData(datatx,datarx);
 }

 public void LoadTx(ref byte[] payload, ushort n){

  byte[] datatx = new Byte[10];
  byte[] datarx = new Byte[10];

  UsbSpi.Settings.SetSpiTxferSize(MCP2210.DllConstants.CURRENT_SETTINGS_ONLY,(ushort)(n+1));
  datatx[0]=0xA0;

  for (int i = 1; i < (n+1); i++) {
datatx[i]=payload[i-1];
  }

  UsbSpi.Functions.TxferSpiData(datatx,datarx);

  UsbSpi.Functions.SetGpioPinVal(0xFFFF);
  System.Threading.Thread.Sleep(0);
  UsbSpi.Functions.SetGpioPinVal(0x0000);
 }

 public void SetAddress(){

  byte[] datatx = new Byte[10];
  byte[] datarx = new Byte[10];

  UsbSpi.Settings.SetSpiTxferSize(MCP2210.DllConstants.CURRENT_SETTINGS_ONLY,6);
  datatx[0]=0x30;
  datatx[1]=0xE7;
  datatx[2]=0xE7;
  datatx[3]=0xE7;
  datatx[4]=0xE7;
  datatx[5]=0xE7;

  UsbSpi.Functions.TxferSpiData(datatx,datarx);
 }

 public void RxData(byte [] buffer){
  byte [] dummy =new Byte[10];

  UsbSpi.Settings.SetSpiTxferSize(MCP2210.DllConstants.CURRENT_SETTINGS_ONLY,5);
  dummy[0]=0x61;
  UsbSpi.Functions.TxferSpiData(dummy,buffer);
  UsbSpi.Settings.SetSpiTxferSize(MCP2210.DllConstants.CURRENT_SETTINGS_ONLY,1);
  dummy[0]=0xE2;
  UsbSpi.Functions.TxferSpiData(dummy,dummy);

  WriteRegister(0x07,0x40);
  //Console.Write("{0}, {1}, {2}, {3}\n",buffer[0],buffer[1],buffer[2],buffer[3]);

 }

 public void TxData(){
  byte [] payload =new Byte[10];

  payload[0]=0x01;
  payload[1]=0x02;
  payload[2]=0x03;
  payload[3]=0x04;

  WriteRegister(0x07,0x7E);
  WriteRegister(0x00,0x3A);
  FlushTxFifo();

  LoadTx(ref payload,4);

 }

 public void DefaultTx(){

  WriteRegister(0x00,0x38);  //mask ints
  WriteRegister(0x04,0x00);  //mask ints
  WriteRegister(0x03,0x03);  //mask ints
  WriteRegister(0x06,0x27);  //mask ints
  WriteRegister(0x05,0x02);  //mask ints
  SetAddress();
  WriteRegister(0x01,0x00);  //mask ints
 }

 public void DefaultRx(){

  WriteRegister(0x00,0x39);  //mask ints
  WriteRegister(0x01,0x00);  //mask ints
  WriteRegister(0x03,0x03);  //mask ints
  WriteRegister(0x06,0x27);  //mask ints
  WriteRegister(0x11,0x04);  //mask ints
  WriteRegister(0x05,0x02);  //mask ints
  SetAddress();
  WriteRegister(0x00,0x3B);  //mask ints

  UsbSpi.Functions.SetGpioPinVal(0xFFFF);


 }

 public nrf24l01p(){

  UsbSpi = new DevIO(MCP2210_VID, MCP2210_PID);
  bool isConnected = false;		   // Connection status variable for MCP2210
  isConnected = UsbSpi.Settings.GetConnectionStatus();

  if (isConnected==true) {
Console.WriteLine("Ligacao com sucesso!");
  }
  else{
Console.Write("Ligacao falhou!");
Console.ReadKey(true);
return;
  }

  byte[] gpiopindes=new Byte[9];

  for (int i = 0; i < 9; i++) {
gpiopindes[i]=0;//GPIO
  }

  gpiopindes[4]=1; //CS
  gpiopindes[6]=2; //IRQ


  UsbSpi.Settings.SetAllChipSettings(MCP2210.DllConstants.CURRENT_SETTINGS_ONLY,gpiopindes,0x0000,0x20,false,0,false);
  UsbSpi.Settings.SetInterruptPinMode(MCP2210.DllConstants.CURRENT_SETTINGS_ONLY,2);


  UsbSpi.Functions.SetGpioPinVal(0x0000);
  System.Threading.Thread.Sleep(1);

 }
}
}

Coloco aqui o código pois pode ajudar alguém...!

Com isto deparo-me agora com outra duvida,

Inicialmente pensei que o conversor de USB para SPI tinha um pino dedicado a interrupções que me iria despoletar um evento cada vez que o fosse a "0" ou a "1" (indicando por exemplo que o módulo de comunicação sem fios recebeu um novo pacote).

Vejo afinal que isto não acontece e que preciso de estar constantemente a fazer polling ao modulo de comunicação sem fios para saber se chegou um novo pacote de dados.

Para ultrapassar esta situação gostaria de criar uma thread dedicada a fazer o polling do modulo de comunicação sem fios e caso haja um novo pacote de dados lançar um evento para o programa principal.

Podem-me dar uma orientação de como fazer?

Cumprimentos, Mauro.

Edited by maurosmartins

Share this post


Link to post
Share on other sites
kalin

Eu sempre que preciso que trabalho assíncrono uso BackgroundWorker, é muito fácil de utilizar.

Podes iniciar um ciclo infinito dentro do evento DoWork e sempre que precisares podes utilizar o método ReportProgress para enviar dados para a thread do teu programa.

Quando precisares de terminar existe também um evento CancelAsync.

Podes encontrar mais detalhes e exemplos na documentação:

http://msdn.microsoft.com/en-us/library/4852et58.aspx

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.