ZEO-S 와 ZEO-IO2 로 8채널 ADC를 모두 사용하는 예제입니다.

 

CDS 8개를 각각 ADC1 ~ ADC8에 연결하고 CDS 밝기에 따라

LED를 ON/OFF 합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

윈도우 프로그램 화면 – 잠깐 동안 CDS를 가렸다가 뗄 경우

 

 

 

 

 

윈도우 프로그램 – CDS를 순차적으로 가린 경우

 

 

 

 

 

   

코드 C#

 

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using ZeoDotNetLib;

using System.Diagnostics;

using System.Threading;

 

namespace ADCTest8CH

{

public partial class Form1 : Form

{

// LED 를 그룹으로 지정

PIN_NAME LED1 = PIN_NAME.PA3 | PIN_NAME.PA4;

PIN_NAME LED2 = PIN_NAME.PA5 | PIN_NAME.PA6;

PIN_NAME LED3 = PIN_NAME.PA7 | PIN_NAME.PA8;

PIN_NAME LED4 = PIN_NAME.PA9 | PIN_NAME.PB12;

PIN_NAME LED5 = PIN_NAME.PB0 | PIN_NAME.PB1;

PIN_NAME LED6 = PIN_NAME.PB2 | PIN_NAME.PB3;

PIN_NAME LED7 = PIN_NAME.PB4 | PIN_NAME.PB5;

PIN_NAME LED8 = PIN_NAME.PB6 | PIN_NAME.PB7;

 

// ZEO용 인스턴스

const int ADC_MEM_SIZE = 0x3C00;

ZeoDotNetLib.ZeoLib ZEO1 = new ZeoDotNetLib.ZeoLib();

 

// 그래픽용

GraphControl GraphCtrl;

 

public Form1()

{

InitializeComponent();

 

this.cboADCSpeed.SelectedIndex = 0;

this.cboReadSpeed.SelectedIndex = 0;

}

 

private void Form1_Load(object sender, EventArgs e)

{

GraphCtrl = new GraphControl(new Font("Arial", 12), new Font("Arial", 10), new Font("Arial", 8));

GraphCtrl.TabIndex = 0;

GraphCtrl.Dock = DockStyle.Fill;

GraphCtrl.Name = "ADC1 ";

 

//Add Graph Control to the form

GraphPanel.Controls.Add(GraphCtrl);

 

//Add series

GraphCtrl.AddPointsSerie("ADC1", Axes.VerticalPrimary, " 1", Color.Red);

GraphCtrl.AddPointsSerie("ADC2", Axes.VerticalPrimary, " 2", Color.Green);

GraphCtrl.AddPointsSerie("ADC3", Axes.VerticalPrimary, " 3", Color.Blue);

GraphCtrl.AddPointsSerie("ADC4", Axes.VerticalPrimary, " 4", Color.DarkBlue);

GraphCtrl.AddPointsSerie("ADC5", Axes.VerticalPrimary, " 5", Color.YellowGreen);

GraphCtrl.AddPointsSerie("ADC6", Axes.VerticalPrimary, " 6", Color.SkyBlue);

GraphCtrl.AddPointsSerie("ADC7", Axes.VerticalPrimary, " 7", Color.Gray);

GraphCtrl.AddPointsSerie("ADC8", Axes.VerticalPrimary, " 8", Color.DarkGreen);

 

GraphCtrl.Invalidate();

 

 

if (FStatus.OK == this.ZEO1.Open())

{

this.ZEO1.InitZeo(ADC_MEM_SIZE);

this.lblBoardInfo.Text = "ZEO-" + this.ZEO1.GetZeroType().ToString() + ", " + this.ZEO1.GetBoardVersion().ToString();

 

this.btnStart.Enabled = this.btnStop.Enabled = true;

this.ZEO1.ADCReceived += new eventADCReceived(ZEO_ADCReceived);

this.ZEO1.Pin_DirOutput(LED1 | LED2 | LED3 | LED4 | LED5 | LED6 | LED7 | LED8);

this.ZEO1.Pin_Reset(LED1 | LED2 | LED3 | LED4 | LED5 | LED6 | LED7 | LED8);

}

else

{

this.lblBoardInfo.Text = "open fail";

this.lblBoardInfo.ForeColor = Color.Red;

}

Thread.Sleep(1000);

}

 

private void Form1_FormClosing(object sender, FormClosingEventArgs e)

{

Thread.Sleep(100);

ZEO1.Close();

}

 

private void btnStart_Click(object sender, EventArgs e)

{

// ADC 8채널 지정

ADCStarter[] _start = new ADCStarter[]{

new ADCStarter(ADCChannel._1,(ADCSpeed1) cboADCSpeed.SelectedIndex),

new ADCStarter(ADCChannel._2,(ADCSpeed1) cboADCSpeed.SelectedIndex),

new ADCStarter(ADCChannel._3,(ADCSpeed1) cboADCSpeed.SelectedIndex),

new ADCStarter(ADCChannel._4,(ADCSpeed1) cboADCSpeed.SelectedIndex),

new ADCStarter(ADCChannel._5,(ADCSpeed1) cboADCSpeed.SelectedIndex),

new ADCStarter(ADCChannel._6,(ADCSpeed1) cboADCSpeed.SelectedIndex),

new ADCStarter(ADCChannel._7,(ADCSpeed1) cboADCSpeed.SelectedIndex),

new ADCStarter(ADCChannel._8,(ADCSpeed1) cboADCSpeed.SelectedIndex),

};

 

this.ZEO1.InitADC1(_start);

this.ZEO1.WaitStandby();

 

}

 

int m_iAdcDiv = 0;

int[] g_iADCData;

 

// ADC 데이터를 받으면

void ZEO_ADCReceived(byte[] bData)

{

 

if (bData == null) return;

if (bData.Length <= 7) return;

 

int iADCChannelCount = this.ZEO1.GetADCChannelCount();

if (iADCChannelCount <= 0) return;

 

UInt16[] uiData = new UInt16[bData.Length / 2];

Buffer.BlockCopy(bData, 0, uiData, 0, bData.Length);

 

g_iADCData = Array.ConvertAll(uiData, new Converter<UInt16, int>(UInt16ToInt32));

 

for (int i = 0; i < g_iADCData.Length; i += (iADCChannelCount * m_iAdcDiv))

{

GraphCtrl.GetPointsSerie("ADC1").AddPoint(g_iADCData[i]);

GraphCtrl.GetPointsSerie("ADC2").AddPoint(g_iADCData[i + 1]);

GraphCtrl.GetPointsSerie("ADC3").AddPoint(g_iADCData[i + 2]);

GraphCtrl.GetPointsSerie("ADC4").AddPoint(g_iADCData[i + 3]);

GraphCtrl.GetPointsSerie("ADC5").AddPoint(g_iADCData[i + 4]);

GraphCtrl.GetPointsSerie("ADC6").AddPoint(g_iADCData[i + 5]);

GraphCtrl.GetPointsSerie("ADC7").AddPoint(g_iADCData[i + 6]);

GraphCtrl.GetPointsSerie("ADC8").AddPoint(g_iADCData[i + 7]);

}

 

// 그래프 refresh

GraphCtrl.Invalidate();

}

 

public static int UInt16ToInt32(UInt16 pf)

{

return Convert.ToInt32(pf);

}

 

private void DisplayResult(string _str)

{

Console.WriteLine(_str);

}

 

private void button2_Click(object sender, EventArgs e)

{

this.ZEO1.DisableADC();

}

 

private void tmrRx_Tick(object sender, EventArgs e)

{

if (g_iADCData == null) return;

 

if (g_iADCData.Length>8)

{

this.ZEO1.Pin_Write(LED1, Convert.ToBoolean(g_iADCData[0] < 750));

this.ZEO1.Pin_Write(LED2, Convert.ToBoolean(g_iADCData[1] < 750));

this.ZEO1.Pin_Write(LED3, Convert.ToBoolean(g_iADCData[2] < 750));

this.ZEO1.Pin_Write(LED4, Convert.ToBoolean(g_iADCData[3] < 750));

this.ZEO1.Pin_Write(LED5, Convert.ToBoolean(g_iADCData[4] < 750));

this.ZEO1.Pin_Write(LED6, Convert.ToBoolean(g_iADCData[5] < 750));

this.ZEO1.Pin_Write(LED7, Convert.ToBoolean(g_iADCData[6] < 750));

this.ZEO1.Pin_Write(LED8, Convert.ToBoolean(g_iADCData[7] < 750));

}

}

 

private void cboReadSpeed_SelectedIndexChanged(object sender, EventArgs e)

{

// 데이터 읽기 간격을 변경하면

m_iAdcDiv = cboReadSpeed.SelectedIndex + 1;

}

 

}

}

 

 

 

 

   

   

전체 코드 Visual C# 2008 용

다운로드

   

출처: http://whiteat.com/bPDS_ZEO/186977 

   

 

 

Posted by WhiteAT
,

 

ZEO-S 의 Pulse Counter 로 스위치 입력을 카운터 해보았습니다. Pulse Counter 로 몇 KHz까지 정확히 읽을 수 있는지 실험해 보겠습니다.

 

ZEO-S 의 PWM (PA11) 과 Pulse Counter (PA12)를 점퍼로 연결합니다. 그러면 PA11의 PWM 출력이 PA12 의 Pulse Counter 로 입력됩니다.

 

 

 

100Khz 의 PWM으로 실험을 진행합니다.

 

 

 

 

 

10초 동안 아래처럼 약 1,000,000 개의 펄스를 입력 받게 됩니다.

 

 

 

 

 

24초 동안 아래처럼 약 24,000,000 개의 펄스를 입력 받게 됩니다.

 

 

 

 

 

 

200Khz 의 PWM에서는 10초 동안 아래처럼 약 2,000,000 개의 펄스를 입력 받게 됩니다.

 

 

200Khz 의 PWM에서도 정확한 카운터를 얻었습니다.

 

 

 

코드 C#

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ZeoDotNetLib;


namespace PulseInputFromPWM
{
  public partial class Form1 : Form
  {
    Double dTotalCnt = 0;
    UInt16 lastCnt = 0;
    ZeoLib ZEO = new ZeoLib();
    int iTmrCnt = 0;

    public Form1()
    {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
      this.ZEO.Open();
      this.ZEO.InitZeo(0);
      this.label1.Text = this.ZEO.ToString();

      this.ZEO.InitCount(7);
     
      // 2Khz 파형 발생
      //this.ZEO.InitPWMC(PWM_Frequency._2Khz, 0, 0, 0, 0);

      // 100Khz 파형 발생
      this.ZEO.InitPWMC(360-1, 0, 0, 0, 0);
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
      this.ZEO.Close();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
      this.GetCounts();
      this.lblTmr.Text = (iTmrCnt++/5).ToString()+"초 경과";
    }
 
    public void GetCounts()
    {
      if (!this.ZEO.IsOpened) return;

      UInt16   _cnt = 0;
      this.ZEO.GetCount(7, out _cnt);


      if (_cnt - lastCnt >=0)
        dTotalCnt += (_cnt-lastCnt);
      else
        dTotalCnt += (_cnt - lastCnt)+65536;

      lastCnt = _cnt  ;

      this.lblTotalCount.Text = dTotalCnt.ToString();
 
    }

    private void btnStart_Click(object sender, EventArgs e)
    {
      this.ZEO.UpdatePWMC(2, 200);
      iTmrCnt = 0;
      dTotalCnt = 0;
    }

    private void btnStop_Click(object sender, EventArgs e)
    {
      this.ZEO.UpdatePWMC(2, 0);
    }
 

  }
}

 

 

 

 

DC 모터 구동에 필요한 PWM, 스텝모터 구동에 사용되는 PULSE 도 ZEO-S의 Pulse Counter로 감시하게 되면 동작 유무를 쉽게 판단할 수 있고, 데이터 라인에 연결하여 데이터 전송되는지 체크하는데 사용할 수도 있습니다.

 

 

전체 코드 Visual C# 2008 용

 

 다운로드



  

출처: http://whiteat.com/185984

 

 

 

 

 

'ZEO 시리즈' 카테고리의 다른 글

ZEO-S, CDS로 빛 밝기 -> LED ON/OFF  (0) 2013.10.30
ZEO-IO2 BOARD – ZEO IO 실험 보드2  (0) 2013.10.28
ZEO-S Pulse Counter, C#  (0) 2013.08.29
ZEO-S, 스위치로 LED ON/OFF, C#  (0) 2013.06.13
ZEO-S, LED 연속으로 이동, C#  (0) 2013.06.08
Posted by WhiteAT
,

 

ZEO-S 로 ADC 을 실험해 보겠습니다.

 

 

 

준비

 

먼저 ZEO-S 의 PB13 핀에 360hz 파형을 입력으로 합니다.

(360hz 파형은 Function Generator 를 이용하시거나 DAC 기능이 있는 MCU 로 만들 수 있습니다. )

 

 

 

 

 

분석 1

 

47.619Khz 로 샘플링을 하면 아래와 같이 됩니다.

 

 

 

 

그래프의 397 픽셀 동안 3개의 파형이 발생합니다.

즉 1주기는 약 132 픽셀에 나타납니다.

 

47.619 Khz / 132 는 약 360 Hz 로 계산됩니다.

 

360Hz 의 파형을 47.619 Khz로 정확히 샘플링 합니다.

 

 

 

 

 

 

 

 

분석 2

 

142.857 Khz 로 샘플링을 하면 아래와 같이 됩니다.

 

 

 

그래프의 397 픽셀 동안 1개의 파형이 발생합니다.

즉 1주기는 약 397 픽셀에 나타납니다.

 

142.857 Khz / 397 는 약 360 Hz 로 계산됩니다.

 

360Hz 의 파형을 142.857 Khz로 정확히 샘플링 합니다.

 

 

 

 

 

 

 

분석 3

 

176.470 Khz 로 샘플링을 하면 아래와 같이 됩니다.

 

 

 

 

 

그래프의 490 픽셀 동안 1개의 파형이 발생합니다.

즉 1주기는 약 490 픽셀에 나타납니다.

 

176.470 Khz / 490 는 약 360 Hz 로 계산됩니다.

 

360Hz 의 파형을 176.470 Khz로 정확히 샘플링 합니다.

 

 

 

 

 

 

 

분석 4

 

142.857 Khz 로 샘플링을 하면 아래와 같이 됩니다.

 

 

 

그래프의 397 픽셀 동안 1개의 파형이 발생합니다.

즉 1주기는 약 397 픽셀에 나타납니다.

 

142.857 Khz / 397 는 약 360 Hz 로 계산됩니다.

 

360Hz 의 파형을 142.857 Khz로 정확히 샘플링 합니다.

 

 

 

 

 

분석 3

 

222.222 Khz 로 샘플링을 하면 아래와 같이 됩니다.

 

 

 

 

 

그래프의 617 픽셀 동안 1개의 파형이 발생합니다.

즉 1주기는 약 617 픽셀에 나타납니다.

 

222.222 Khz / 617 는 약 360 Hz 로 계산됩니다.

 

 

360Hz 의 파형을 222.222 Khz로 샘플링하게 되면 손실데이터가 발생하는데, 이는

ZEO-S 에 있는 ADC 데이터를 컴퓨터에서 빠르게 가져오지 못해 발생하는 겁니다.

(위 그림에서는 2151개의 손실 데이터 발생)

 

이 문제를 해결할 수 있는 방법이 몇 가지 있습니다.

  • 컴퓨터 하드웨어 업그레이드
  • ZEO 용 응용 프로그램 외 모든 프로세스 종료(특히 인터넷, 백신)
  • 메모리가 큰 ZEO-M 으로 대체

 

 

ZEO-S 의 빠른 ADC 데이터 처리는 컴퓨터 사양에 큰 영향을 받습니다.

손실된 데이터 값을 잘 체크하여 최대의 샘플링 주기를 찾으셔야 합니다.

 

 

출처: http://whiteat.com/46280

 



Posted by WhiteAT
,