Ir para o conteúdo
maurosmartins

DLL que depende de outra DLL

Mensagens Recomendadas

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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.

Editado por maurosmartins

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.