Getting started with Arduino and WIZ820io

From MCS Wiki
Jump to: navigation, search

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:

  1. Open AVR Studio 6
  2. Hit Tools >>> Device Programming
  3. Select AVRISP mkII under Tools and Select ATMEGA328P under devices and hit Apply button
  4. Check the BOORST fuse bit (see picture below)
  5. Flash the bootloader to Atmega328P
Avr sdudio 6 fuse bits bootloader.PNG


How to flash the bootloader

  1. Goto Memories
  2. Select the Bootloader HEX file
  3. Hit the Program button


Avr sdudio 6 fuse bits bootloader flash.PNG


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:

 

  1. Goto Options >>> Programmer in Bascom-AVR
  2. Select MCS Bootloader
  3. Select the com port of Arduino (in this case com3) and baud rate = 57600 (the same as in the bootloader program)
  4. Write the first Hello World program
Arduino bootloader settings in bascom avr.PNG


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

Wiz820io first test.jpg


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.


Easy tcp ip tool.PNG


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

Personal tools
Namespaces
Variants
Actions
Navigation
Language