Getting started with Arduino and WIZ820io
See also: [1]
Contents |
Used Bascom-AVR Version
Bascom-AVR 2.0.7.6
Used OS = Windows8
Used Hardware
To get started an Arduino Duemilanove board is used with an Arduino prototyping shield and prototyping jump wires.
To get the 3.3V for the WIZ820io power supply an voltage regulator is needed to transform the 5V from the Arduino board to 3.3V.
(The maximum current draw from FTDI chip on the Arduino Duemilanove is max. 50mA and therefore not usable to power the WIZ820io)
Used Boot loader
You can use the Arduino boot loader but in this example an AVRISP MKII is used to flash an Bascom-AVR Bootloader.
For this you need an AVRISP MKII and AVR Studio to flash the bootloader on the Atmega328P on the Arduino.
Steps:
- Open AVR Studio 6
- Hit Tools >>> Device Programming
- Select AVRISP mkII under Tools and Select ATMEGA328P under devices and hit Apply button
- Check the BOORST fuse bit (see picture below)
- Flash the bootloader to Atmega328P
How to flash the bootloader
- Goto Memories
- Select the Bootloader HEX file
- Hit the Program button
Following you can find the Bootloader written in Bascom-AVR which works with baud rate of 57600baud:
$crystal = 16000000 'Arduino is running at 16MHz $baud = 57600 '57600 Baud $timeout = 900000 $regfile = "m328pdef.dat" $loader = $3c00 'sets the bootsize to 1024 words under flash size Const Pagemsb = 6 '64 words in a page reguires 6 bits Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim Retries As Byte Dim Receivedbyte As Byte Dim Kindofdata As Byte Dim Spmcsrvalue As Byte Dim Calculatedchecksum As Byte Dim Receivedblock As Byte Dim Countedblock As Byte Dim Invertedblock As Byte Dim Receivedchecksum As Byte Dim Receivedbytes(128) As Byte Dim J As Byte Dim Vl As Byte Dim Vh As Byte Dim Wrd As Word Dim Page As Word Dim Z As Long Disable Interrupts Const Maxword =(2 ^ Pagemsb) * 2 Const Zpagemsb = Pagemsb + 1 Const Soh = &H01 Const Stx = &H02 Const Eot = &H04 Const Ack = &H06 Const Nak = &H15 Const Can = &H18 Retries = 5 Testformagicbyte: Receivedbyte = Waitkey() Print Chr(receivedbyte); If Receivedbyte = 123 Then Kindofdata = 0 Goto Loader Elseif Receivedbyte = 124 Then Kindofdata = 1 Goto Loader Elseif Receivedbyte <> 0 Then Decr Retries If Retries <> 0 Then Goto Testformagicbyte End If Goto _reset Loader: Do Receivedbyte = Waitkey() Loop Until Receivedbyte = 0 If Kindofdata = 0 Then Spmcsrvalue = 3 : Gosub Do_spm Spmcsrvalue = 17 : Gosub Do_spm End If Retries = 10 Do Calculatedchecksum = 0 Print Chr(nak); Do Receivedbyte = Waitkey() Select Case Receivedbyte Case &H01: '<SOH> Incr Countedblock Calculatedchecksum = 1 Receivedblock = Waitkey() Calculatedchecksum = Calculatedchecksum + Receivedblock Invertedblock = Waitkey() Calculatedchecksum = Calculatedchecksum + Invertedblock For J = 1 To 128 Receivedbytes(j) = Waitkey() Calculatedchecksum = Calculatedchecksum + Receivedbytes(j) Next Receivedchecksum = Waitkey() If Countedblock = Receivedblock Then If Receivedchecksum = Calculatedchecksum Then Gosub Writepage Print Chr(ack); Else Print Chr(nak); End If Else Print Chr(nak); End If Case &H04: '<EOT> If Wrd > 0 And Kindofdata = 0 Then Wrd = 0 Spmcsrvalue = 5 : Gosub Do_spm Spmcsrvalue = 17 : Gosub Do_spm End If Print Chr(ack); Waitms 20 Goto _reset Case &H18: '<CAN> Goto _reset Case Else Exit Do End Select Loop If Retries > 0 Then Waitms 1000 Decr Retries Else Goto _reset End If Loop Writepage: If Kindofdata = 0 Then For J = 1 To 128 Step 2 Vl = Receivedbytes(j) Vh = Receivedbytes(j + 1) lds r0, {vl} lds r1, {vh} Spmcsrvalue = 1 : Gosub Do_spm Wrd = Wrd + 2 If Wrd = Maxword Then Wrd = 0 Spmcsrvalue = 5 : Gosub Do_spm Spmcsrvalue = 17 : Gosub Do_spm Page = Page + 1 Spmcsrvalue = 3 : Gosub Do_spm Spmcsrvalue = 17 : Gosub Do_spm End If Next Else For J = 1 To 128 Writeeeprom Receivedbytes(j) , Wrd Wrd = Wrd + 1 Next End If Return Do_spm: Bitwait Spmcsr.0 , Reset Bitwait Eecr.1 , Reset Z = Page Shift Z , Left , Zpagemsb Z = Z + Wrd lds r30, {Z} lds r31, {Z + 1} #if _romsize > 65536 lds r24, {Z + 2} sts rampz, r24 #endif Spmcsr = Spmcsrvalue spm nop nop Return
First "Hello World" Program
Next Step is to flash a first Hello World program direct with Bascom-AVR:
- Goto Options >>> Programmer in Bascom-AVR
- Select MCS Bootloader
- Select the com port of Arduino (in this case com3) and baud rate = 57600 (the same as in the bootloader program)
- Write the first Hello World program
Source code for Hello World program:
$regfile = "m328pdef.dat" $crystal = 16000000 '16MHz $hwstack = 60 $swstack = 60 $framesize = 60 Config Com1 = 57600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Do Print "Hello World" Waitms 1000 Loop End 'end program
Just compile this Hello World program and hit the Program Chip button or use shortcut F4 in Bascom-AVR (the programmer should be already configured before).
Then open an terminal program of your choice and connect with 57600 baud on the Arduino interface number (in this case COM3) and you will notice the
Hello World messages coming in.
Now it's time to start with WIZ820io.
Hardware Connections for WIZ820io
HARDWARE CONNECTIONS:
WIZ820io |
Arduino |
GND |
GND |
MISO |
MISO |
MOSI |
MOSI |
SCK |
SCK |
nSS |
Portd.7 |
nReset |
Portb.2 |
PWDN |
GND |
3.3V (over additional voltage regulator) |
5V input for additional voltage regulator |
nINT |
not connected |
SPI and TCPIP Configuration for WIZ820io
At first we need to configure the SPI interface and initialize the SPI interface. Then we need a defined Reset of the WIZ820io before we configure the TCPIP Interface. Important is also the waitms 350 to give the WIZ820io time to be ready for the first command.
Needed infos are:
- We use noint. This is the preferred method.
- MAC address of WIZ820io
- IP address of WIZ820io
- Subnet Mask
- Gateway (e.g. Router adress)
- Local Port
- Chip is here W5200 which is used in the WIZ820io module
- SPI = 1. THe W5200 chip is connected with SPI.
- Chip select is connected with Portd.7
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 0 Spiinit Config Pinb.2 = Output W5200_nreset Alias Portb.2 Reset W5200_nreset Waitms 1 Set W5200_nreset Waitms 350 Print Enable Interrupts 'Here you need MAC address, the ip address you like to use, subnet mask, gateway and localport Config Tcpip = Noint , _ Mac = 1.1.94.127.1.255 , _ Ip = 192.168.2.254 , _ Submask = 255.255.255.0 , _ Gateway = 192.168.2.1 , _ Localport = 1000 , _ Chip = W5200 , _ Spi = 1 , _ Cs = Portd.7
First Test Hardware
Easy TCP/IP
The following code can be used with the Easy TCP/IP tool in Bascom-AVR under Tools >>> Easy TCP/IP.
In the Easy TCP/IP tool you need:
- The IP address of WIZ820io (e.g. 192.168.2.254)
- Local Port (e.g. 50000)
- Remort Port (e.g. 1000)
- And a text (e.g. Hello)
Hit Setup UDP then you can send the text by klicking on SEND.
And here the Terminal Output of the following source code in combination with Easy TCP/IP:
-----START WIZ820io Arduino Duemilanove DEMO-----
PING NTP Server : 192.53.103.108
Ping Number : 1
PING OK --> Exit Do..Loop
Socket 0 0
Local_time = 416047437
08.03.13 09:43:57
Size= 5 By Port= 50000 Sender IP= 192.168.2.100 Timestamp : 08.03.13 / 09:44:14
DATA = Hello
Bascom-AVR source code of UDP Example which uses:
- Ping of NTP Server
- Get time from NTP Server
- Send back the text to sender IP address (sent by Easy TCP/IP)
Demo Code
' IP Address of Arduino = 192.168.2.254 ' Port of Arduino = 1000 ' We use UDP ' ' HARDWARE CONNECTIONS: ' WIZ820 <-------------> Arduino Duemilanove ' GND <-------------> GND ' MISO <-------------> MISO ' MOSI <-------------> MOSI ' SCK <-------------> SCK ' nSS <-------------> PortD.7 ' nReset <-------------> PortB.2 ' nINT ' PWDN <-------------> GND ' 3.3V <-------------> 3.3V over additional 3.3 V Low Dropouts (LDO) ' NTP Server IP address (here you can change the NTP server of your choice) Const Ntp1 = 192 : Const Ntp2 = 53 : Const Ntp3 = 103 : Const Ntp4 = 108 ' Example = 192.53.103.108 Const Use_ping = 1 'use PING NTP server for checking NTP server availability before move on $regfile = "m328pdef.dat" $crystal = 16000000 '16MHz $hwstack = 100 $swstack = 100 $framesize = 400 Config Com1 = 57600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 '------------------------------------------------------------------------------- ' Server Variables '------------------------------------------------------------------------------- Dim Ip_sntp_server As Long 'assign the IP number of a SNTP server Ip_sntp_server = Maketcp(ntp1 , Ntp2 , Ntp3 , Ntp4) 'assign IP of NTP SERVER Wait 2 Print Print "-----START WIZ820io Arduino Duemilanove DEMO-----" '------------------------------------------------------------------------------- ' Network Hardware '------------------------------------------------------------------------------- Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 0 Spiinit Config Pinb.2 = Output W5200_nreset Alias Portb.2 Reset W5200_nreset Waitms 1 Set W5200_nreset Waitms 350 Print Enable Interrupts 'Here you need MAC address, the ip address you like to use, subnet mask, gateway and localport Config Tcpip = Noint , _ Mac = 1.1.94.127.1.255 , _ Ip = 192.168.2.254 , _ Submask = 255.255.255.0 , _ Gateway = 192.168.2.1 , _ Localport = 1000 , _ Chip = W5200 , _ Spi = 1 , _ Cs = Portd.7 '------------------------------------------------------------------------------- ' Config Clock '------------------------------------------------------------------------------- Dim Local_time As Long Dim New_second As Bit Config Date = Dmy , Separator = . Config Clock = User Config Timer1 = Timer , Prescale = 256 On Timer1 Timer_irq Saveall 'the SAVEALL option is NEEDED ! Const Timer_preload = 3036 Enable Timer1 '------------------------------------------------------------------------------- ' UDP '------------------------------------------------------------------------------- Dim Idx As Byte ' socket number Dim Result As Word ' result Dim S(255) As Byte Dim R(255) As Byte Dim Sstr As String * 255 Dim Temp As Byte , Temp2 As Byte ' temp bytes Dim Ip As Long '------------------------------------------------------------------------------- ' PING NTP SERVER to check if NTP server is available '------------------------------------------------------------------------------- #if Use_ping = 1 Dim J As Byte , Res As Byte Dim Ii As Byte Dim Ping_check_ok As Bit ' FILL PING ARRAY S(1) = 8 'type is echo S(2) = 0 'code S(3) = 0 ' for checksum initialization S(4) = 0 ' checksum S(5) = 0 ' a signature can be any number S(6) = 1 ' signature S(7) = 0 ' sequence number - any number S(8) = 1 S(9) = 65 Dim W As Word At S + 2 Overlay 'same as dta(3) and dta(4) Dim B As Byte W = Tcpchecksum(s(1) , 9) ' calculate checksum and store in dta(3) and dta(4) 'Ip = Maketcp(192.53.103.108) 'try to check this google server Print "PING NTP Server : " ; Ip2str(ip_sntp_server) 'Print "Socket " ; Idx ; " " ; Idx Setipprotocol Idx , 1 'set protocol to 1 'the protocol value must be set BEFORE the socket is openend Idx = Getsocket(idx , Sock_ipl_raw , 5000 , 0) 'RAW Socket ' We try the PING 3 times (but if we get an answer we exit the for loop) Do Incr Ii Result = Udpwrite(ip_sntp_server , 7 , Idx , S(1) , 9) 'write ping data ' Print "Ping Number : " ; ii Waitms 200 ' depending on the hops, speed, etc Result = Socketstat(idx , Sel_recv) 'check for data ' Print "REC:" ; Result If Result >= 11 Then Res = Tcpread(idx , R(1) , Result) 'get data with TCPREAD !!! ' Print "DATA RETURNED :" ; Res '( ' For J = 1 To Result Print R(j) ; " " ; Next Print ') Print "PING OK --> Exit Do..Loop" Set Ping_check_ok Exit Do ' If we can an answer from NTP Server exit do ... loop Else Print "NTP Server not available" End If Waitms 100 Loop Until Ii = 3 Ii = 0 #else Dim Ping_check_ok As Bit Ping_check_ok = 1 #endif '------------------------------------------------------------------------------- ' SNTP '------------------------------------------------------------------------------- If Ping_check_ok = 1 Then 'When the NTP Serverer responded to PING 'we need to get a socket first 'note that for UDP we specify sock_dgram Idx = Getsocket(idx , Sock_dgram , 1000 , 0) ' get socket for UDP mode, specify port Print "Socket " ; Idx ; " " ; Idx Local_time = Sntp(idx , Ip_sntp_server) ' get time from SNTP server Print "Local_time = " ; Local_time If Local_time < 100 Then 'try it again Wait 1 Local_time = Sntp(idx , Ip_sntp_server) ' get time from SNTP server Print "Second try ; Local_time = " ; Local_time End If Local_time = Local_time + 3600 ' (UTC/GMT) time + 3600 Print Date(local_time) ; Spc(3) ; Time(local_time) End If 'get a socket first 'note that for UDP we specify sock_dgram Idx = Getsocket(idx , Sock_dgram , 1000 , 0) ' get socket for UDP mode, specify port 'Print "Socket " ; Idx ; " " ; Idx Do If New_second = 1 Then Reset New_second 'Do something every second ...... End If 'The UDP header give us info about Peersize, Peerport and peeraddress 'which is the amount of data bytes received from peerport and peer ip address Udpreadheader Idx ' read the udp header (only the first 8 Bytes) If Peersize > 0 Then ' the actual number of bytes (without header bytes) Print "Size= " ; Peersize ; " By" ; " Port= " ; Peerport ; " Sender IP= " ; Ip2str(peeraddress) ; " Timestamp : " ; Date$ ; " / " ; Time$ Temp = Udpread(idx , S(1) , Peersize) ' read the number of Bytes into Array S Print "DATA = " ; For Temp = 1 To Peersize Print Chr(s(temp)) ; ' print what we have received over USART to debug interface Next Print 'Send it back to sender IP, Sender Port Result = Udpwrite(peeraddress , Peerport , Idx , S(1) , Peersize) ' write the received data back End If Loop End Timer_irq: Incr Local_time Time$ = Time(local_time) Date$ = Date(local_time) Set New_second Return Getdatetime: Return Settime: Return Setdate: Return
Author
MAK3