2016年9月20日 星期二

[C#] 網路程式練習



C# TCP 客戶端 2 種 (最小精簡) 寫法:
https://lolikitty.pixnet.net/blog/post/112329777


Get Local IP Address in C#
https://www.delftstack.com/howto/csharp/get-local-ip-address-in-csharp/


書本上操寫的範例:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Net;

namespace ConsoleApplication_Internet_1
{
    class Program
    {
        static void Main(string[] args)
        {
            //create IP address
            IPAddress ipAddr = IPAddress.Parse("210.59.154.30");
            Console.WriteLine("ipAddr=" + ipAddr);

            //create IP endpoint
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 80);
            Console.WriteLine("ipEndPoint" + ipEndPoint);

            // IP Endpoint 序列化為 SocketAddress
            SocketAddress socketAddr = ipEndPoint.Serialize();
            Console.WriteLine("socketAddr=" + socketAddr);

            Console.ReadKey();
        }
    }

}

執行結果:


繼續 key.....


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Net;
using System.Net.Sockets;

namespace ConsoleApplication_Internet_1
{
    class Program
    {
        static void Main(string[] args)
        {
            //create IP address
            IPAddress ipAddr = IPAddress.Parse("210.59.154.30");
            Console.WriteLine("ipAddr=" + ipAddr);

            //create IP endpoint
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 80);
            Console.WriteLine("ipEndPoint" + ipEndPoint);

            // IP Endpoint 序列化為 SocketAddress
            SocketAddress socketAddr = ipEndPoint.Serialize();
            Console.WriteLine("socketAddr =  " + socketAddr);

            //透過 DNS 找尋IP位址相對應之主機名稱
            IPHostEntry remoteHostEntry = Dns.GetHostEntry(ipAddr);
            Console.WriteLine("host of ip:" + ipAddr + "is" + remoteHostEntry.HostName);


            //由於主機有可能有一個以上的 Alias
            //因此程式中以迴圈方式判斷 Alias
            string[] aliasList = remoteHostEntry.Aliases;
            for(int i=0;i<=aliasList.Length-1;i++)
            {
                Console.WriteLine("Alias " + i + " : " + aliasList[i]);
            }


            //由於主機有可能有一個以上的IP address
            //因此主程式中以迴圈方式判斷 AddressList
            IPAddress[] addrList = remoteHostEntry.AddressList;
            for(int i=0;i<addrList.Length-1;i++)
            {
                Console.WriteLine("Address " + i + " : " + addrList[i]);
            }


            Console.ReadKey();
        }
    }

}





2016年9月14日 星期三

[Raspberry] 在Raspberry Pi 2 使用SPI(一)

Enable SPI Kernel Module

ls /dev 會看到有 spidev0.0 spidev0.1



程式::

#include <cstdlib>

#include <stdio.h>

#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include <unistd.h>

#include <string.h>

using namespace std;

int spi_cs0_fd;

unsigned char spi_mode;
unsigned char spi_bitsPerWord;
unsigned int spi_speed;


int spiOpenPort()
{
    int *spi_cs_fd;
   
    int status_value=-1;
   
    spi_mode=SPI_MODE_0;
    spi_bitsPerWord=8;
    spi_speed=1000000;
   
    spi_cs_fd=&spi_cs0_fd;
   
    *spi_cs_fd=open("/dev/spidev0.0",O_RDWR);
   
    if(*spi_cs_fd<0)
    {
        printf("Open /dev/spidev0.0 failed\r\n");
        exit(1);
    }
   
    status_value=ioctl(*spi_cs_fd,SPI_IOC_WR_MODE,&spi_mode);
    if(status_value<0)
    {
        printf("W spi_mode failed\r\n");
        exit(1);
    }
   
    status_value=ioctl(*spi_cs_fd,SPI_IOC_RD_MODE,&spi_mode);
    if(status_value<0)
    {
        printf("RD spi_mode failed\r\n");
        exit(1);
    }
   
    status_value=ioctl(*spi_cs_fd,SPI_IOC_WR_BITS_PER_WORD,&spi_bitsPerWord);
    if(status_value<0)
    {
        printf("WR sp_bitsPerWord failed\r\n");
        exit(1);
    }
   
    status_value=ioctl(*spi_cs_fd,SPI_IOC_RD_BITS_PER_WORD,&spi_bitsPerWord);
    if(status_value<0)
    {
        printf("RD sp_bitsPerWord failed\r\n");
        exit(1);
    }
   
    status_value=ioctl(*spi_cs_fd,SPI_IOC_WR_MAX_SPEED_HZ,&spi_speed);
    if(status_value<0)
    {
        printf("WR spi_spped failed\r\n");
        exit(1);
    }
       
    status_value=ioctl(*spi_cs_fd,SPI_IOC_RD_MAX_SPEED_HZ,&spi_speed);
    if(status_value<0)
    {
        printf("RD spi_spped failed\r\n");
        exit(1);
    }
         
    return(status_value);   
}


int SpiWriteAndRead(unsigned char *data,int length)
{
    struct spi_ioc_transfer spi[length];
    int i=0;
    int retVal =-1;
    int *spi_cs_fd;
   
    spi_cs_fd=&spi_cs0_fd;
   
    for(i=0;i<length;i++)
    {
        memset(&spi[i],0,sizeof(spi[i]));
        spi[i].tx_buf=(unsigned long)(data+i);
        spi[i].rx_buf=(unsigned long)(data+i);
        spi[i].len=sizeof(*(data+i));
        spi[i].delay_usecs=0;
        spi[i].speed_hz=spi_speed;
        spi[i].bits_per_word=spi_bitsPerWord;
        spi[i].cs_change=0;
    }
   
    retVal=ioctl(*spi_cs_fd,SPI_IOC_MESSAGE(length),&spi);
   
    if(retVal<0)
    {
        printf("tran error \n\r");
        exit(1);
    }
    return retVal;  
}


int main(int argc, char** argv) {

    unsigned char buffer[100];
   
    for(int j=0;j<100;j++)buffer[j]=0x55;
   
    if(spiOpenPort()<0)
    {
        return -1;
    }

    SpiWriteAndRead(buffer,100);
   
    close(spi_cs0_fd);
   
    return 0;
}





 參考資料:

Using the SPI Interface
C library for Broadcom BCM 2835 as used in Raspberry Pi
Interfacing an SPI ADC(MCP3008) chip to Raspberry Pi using C++(spidev)




















2016年9月13日 星期二

[Raspberry] 在Raspberry Pi 2 使用SPI

C library for Broadcom BCM 2835 as used in Raspberry Pi 提及:
in order for bcm2835 library SPI to work, you may need to disable the SPI kernel module using:
sudo raspi-config
under Advanced Options - enable Device Tree
under Advanced Options - disable SPI
Reboot.
所以我就跟著做了…..


程式:
#include <cstdlib>

#include <bcm2835.h>
#include <unistd.h>
#include <stdio.h>

using namespace std;

int main(int argc, char** argv) {

    bcm2835_init();
   
    //setup spi pins
    if(bcm2835_spi_begin()==0)
    {
        printf("init failed \r\n");
        return -1;
    }
   
    //set CS pins polarity to low
    bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0,0);
    bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS1,0);
  
    //set clock speed
    bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_32768);
   
    //set SPI data mode
    bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);
   
   
    //Set with CS pin to use for next transfers
    bcm2835_spi_chipSelect(BCM2835_SPI_CS0);
   
    //transfer  byte
    char buf[100];
    for(int j=0;j<100;j++)
    {
        buf[j]=0x55;
    }
    for(int j=0;j<10;j++)
    {
     bcm2835_spi_transfern(&buf[0],100);
    
     bcm2835_delay(1000);

    }
  
    //return spi pins to default input state
    bcm2835_spi_end();
    return 0;
}
從示波器上,發現只有j=0才會有CLK,其他時間CLK都不見(是否是因為沒接裝置沒有正常回應…)...不知勒


2016年9月12日 星期一

[Raspberry] 在Raspberry Pi 2 使用GPIO(三)

sudo –i    charge to root user  -->這樣就可root操作了嗎?

下載BCM2835套件,解壓縮後,進入資料夾
./configure   -->設定連結
make
sudo make check   -->編譯前檢查
sudo make install   -->編譯並進行安裝


程式:

#include <cstdlib>

#include <stdio.h>
#include <unistd.h>

#include <bcm2835.h>

#define PIN RPI_BPLUS_GPIO_J8_08

using namespace std;

int main(int argc, char** argv) {

    if(!bcm2835_init())
    {
        printf("err\r\n");
    }  
   
    bcm2835_gpio_fsel(PIN,BCM2835_GPIO_FSEL_OUTP);
   
    for(int i=1;i<10;i++)
    {
        bcm2835_gpio_write(PIN,HIGH);
        sleep(1);
        bcm2835_gpio_write(PIN,LOW);
        sleep(1);
    }
  
    return 0;
}


當編譯時,出現許多錯誤訊息
Undefined reference to bcm2835_init
Undefined reference to bcm2835_gpio_fsel ….

NetBeans 視窗中,
Run -->Set Project Configuration -->Customize
在左邊選 Linker,右邊的 Libraries 點選加入(會出現 Debug-Libraries)
在右邊點選 Add Option (出現 Select Option)
checkbox Other Option ,輸入 –lbcm2835

跑程式,成功了!!





參考資料:

讓你的Raspberry Pi 透過 GPIO 閃爍 LED

Raspberry Pi –控制內建LED PWR LED ACT LED

Linux GPIO Driver Guide


RPi GPIO Code Samples

[How To Raspberry Pi] 使用C語言控制GPIO (安裝BCM2835套件)

Adding A Library To A NetBeans Project

[Raspberry] 在Raspberry Pi 2 使用GPIO(二)

程式:

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>


using namespace std;


int pin=14;

void CloseExport()
{
    int fd;
    ssize_t byte_write;
    char buf[3];
   
    fd=open("/sys/class/gpio/unexport",O_WRONLY);
       
    if(fd==-1) printf("Failed to open unexport \r\n");
           
    byte_write=snprintf(buf,3,"%d",pin);
       
    if(write(fd,buf,byte_write)<0)   printf("Failed 1\r\n");
 
    close(fd);
}


int main(int argc, char** argv) {

    ssize_t byte_write0;

    int fd1;
   
    char buf0[3];
    fd1=open("/sys/class/gpio/export",O_WRONLY);
   
    if(fd1==-1) {  printf("failed to open export for writing\r\n");return -1;}
   
    byte_write0=snprintf(buf0,3,"%d",pin);
    if(write(fd1,buf0,byte_write0)<0)
    {
        close(fd1);
       
        printf("fail 0\r\n");    
   
        CloseExport();
   
        return-1;
       
    }
    close(fd1);

   
    int fd3;
    char buf1[35];
    snprintf(buf1,35,"/sys/class/gpio/gpio%d/direction",pin);
    fd3=open(buf1,O_WRONLY);
    if(fd3==-1)
    {  
        printf("failed to open gpio direction for writing\r\n");
       
        CloseExport();
     
        return-1;
    }
    if(write(fd3,"out",3)<0)
    {
        close(fd3);
       
        printf("Failed to set direction\r\n");
   
        CloseExport();
   
        return-1;
    }
    close(fd3);
   

    int fd5;
    char buf2[30];
   
    snprintf(buf2,30,"/sys/class/gpio/gpio%d/value",pin);
    fd5=open(buf2,O_WRONLY);
    if(fd5==-1)
    {
        printf("Failed to open gpio value for writing\r\n");
        CloseExport();
        return -1;
    }
   
    if(write(fd5,"1",1)<0)
    {
        close(fd5);
        printf("Failedto set 1");
        CloseExport();
        return -1;
    }
    close(fd5);

    sleep(1);
    printf("Success !!\r\n");
    CloseExport();
     
    return 0;
}

2016年9月11日 星期日

[Raspberry] 在Raspberry Pi 2 使用GPIO(一)

查看gpio的物理地址:
cat /proc/iomem |grep  gpio | grep gpio
3f2000000=3f20000b3 : /soc/gpio@7e200000                         

程式:

#include <cstdlib>

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>

#define BCM2708_PERI_BASE 0x3F000000  //0x20000000 --> Raspberry Pi的位址
#define GPIO_BASE (BCM2708_PERI_BASE +0x200000) /* GPIO controller*/
#define PAGE_SIZE  (4*1024)
#define BLOCK_SIZE (4*1024)

int mem_fd;
void *gpio_map;

//IO access
volatile unsigned *gpio;

//GPIO setup macros. Always use INP_GPIO(x) before using 
//OUT_GPIO(x) or SET_GPIO_ALT(x,y) 
#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3))
#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))

#define GPIO_SET *(gpio+7)  //sets bits which are 1 ignores bits which are 0
#define GPIO_CLR *(gpio+10) //clears bits which are 1 ignores bits which are 0
#define GET_GPIO(g) (*(gpio+13)&(1<<g)) //0 if Low, (1<<g) if High
#define GPIO_PULL *(gpio+37) //pull up/pull down

using namespace std;

void setup_io()
{
    if((mem_fd = open("/dev/mem",O_RDWR|O_SYNC))<0)
    {
        printf("Can not open /dev/mem \n");
        exit(-1);
    }
    
    //map GPIO
    gpio_map=mmap(
            NULL,                   //anyadress inourspace will do
            BLOCK_SIZE,             //map length
            PROT_READ|PROT_WRITE,   //enable reading & writting to mappedmemory
            MAP_SHARED,             //shared with other processes
            mem_fd,                 //fileto map
            GPIO_BASE               //offset to GPIOperipheral
            );
    
    close(mem_fd);      //No need to keep mem_fd open after map
    
    if(gpio_map==MAP_FAILED){
        printf("mmap error %d\n",(int)gpio_map);    //errnoalso set
        exit(-1);
    }   
    gpio=(volatile unsigned*)gpio_map;
}


int main(int argc, char** argv) {

    //set up gpi pointer for direct register access
    setup_io();

    printf("step 1 ok\r\n");    
    
    //MustuseINP_GPIO before we can use OUT_GPIO
    INP_GPIO(14);
    OUT_GPIO(14);

    for(int j=0;j<10;j++)
    {
        GPIO_SET=1<<14;
        sleep(1);
        GPIO_CLR=1<<14;
        sleep(1);
    }
        
    return 0;
}



開始跑出現 can not open /dev/mem,就停下來了

進入 NetBeans IDE 8.1 視窗
選擇 Run --> Set Project Configuration -->Customize…
左邊選擇Run,在右邊Run Command,加入 sudo
“${OUTPUT_PATH}” --> sudo “${OUTPUT_PATH}”      
成功運行了 !!!


[Raspberry] 在Raspberry Pi 2 使用GPIO

原來在終端機上,這樣就可操控 GPIO:

操控 UART的TX(先把 UART disable了)
echo 14 > /sys/class/gpio/export  -->設定可控制
echo out > /sys/class/gpio/gpio14/direction  -->輸出腳
echo 1 > /sys/class/gpio/gpio14/value  -->輸出1
echo 0 > /sys/class/gpio/gpio14/value  -->輸出0
echo 14 > /sys/class/gpio/unexport  -->取消建立出的 node


使用 GPIO readall 可看到 IO 的輸出(IN or out/0 or 1)



使用 debugfs 來觀看目前的GPIO設定
sudo mount –t debugfs   debugfs /sys/kernel/debug
mount:debugfs is already mounted or /sys/kernel/debug busy
sudo cat /sys/kernel/debug/gpio
GPIOs 0-53 platform/3f2000000.gpio  pinctrl-bcm2835:
gpio-14 (      |sysfs  )  out    hi
gpio-35 (      |?     )   in    hi 

gpio-47  (     |?    )   out   lo