This commit is contained in:
Wolfgang Hottgenroth 2015-05-02 00:14:40 +02:00
commit 40e18d4172
40 changed files with 6547 additions and 0 deletions

64
.cproject Normal file
View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="it.baeyens.arduino.core.toolChain.release.1600398586">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="it.baeyens.arduino.core.toolChain.release.1600398586" moduleId="org.eclipse.cdt.core.settings" name="Release">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildProperties="" description="" id="it.baeyens.arduino.core.toolChain.release.1600398586" name="Release" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="it.baeyens.arduino.core.toolChain.release.1600398586.1851093318" name="/" resourcePath="">
<toolChain id="it.baeyens.arduino.core.toolChain.release.780212274" name="Arduino Toolchain" superClass="it.baeyens.arduino.core.toolChain.release">
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="it.baeyens.arduino.targetplatform.1836264714" name="Arduino Target" osList="all" superClass="it.baeyens.arduino.targetplatform"/>
<builder buildPath="${workspace_loc:/WiModbusGateway}/Release" id="it.baeyens.arduino.sketch.builder.1757422331" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Arduino sketch builder" superClass="it.baeyens.arduino.sketch.builder"/>
<tool id="it.baeyens.arduino.tool.sketch.compiler.cpp.1866421605" name="Arduino C++ Compiler" superClass="it.baeyens.arduino.tool.sketch.compiler.cpp">
<option id="it.baeyens.arduino.compiler.cpp.sketch.option.incpath.2008512007" name="Include Paths (-I)" superClass="it.baeyens.arduino.compiler.cpp.sketch.option.incpath" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/WiModbusGateway/arduino/core}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/WiModbusGateway/arduino/variant}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/WiModbusGateway/SPI}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/WiModbusGateway/WiFi}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/WiModbusGateway/LiquidCrystal}&quot;"/>
</option>
<inputType id="it.baeyens.arduino.compiler.cpp.sketch.input.416726280" name="CPP source files" superClass="it.baeyens.arduino.compiler.cpp.sketch.input"/>
</tool>
<tool id="it.baeyens.arduino.tool.compiler.c.202457829" name="Arduino C Compiler" superClass="it.baeyens.arduino.tool.compiler.c">
<option id="it.baeyens.arduino.compiler.c.sketch.option.incpath.1559551443" name="Include Paths (-I)" superClass="it.baeyens.arduino.compiler.c.sketch.option.incpath" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/WiModbusGateway/arduino/core}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/WiModbusGateway/arduino/variant}&quot;"/>
</option>
<inputType id="it.baeyens.arduino.compiler.c.sketch.input.83886313" name="C Source Files" superClass="it.baeyens.arduino.compiler.c.sketch.input"/>
</tool>
<tool id="it.baeyens.arduino.tool.sketch.compiler.s.1872776956" name="Arduino Assembler" superClass="it.baeyens.arduino.tool.sketch.compiler.s"/>
<tool id="it.baeyens.arduino.tool.ar.431051807" name="Arduino archiver" superClass="it.baeyens.arduino.tool.ar"/>
<tool id="it.baeyens.arduino.tool.combine.986542672" name="Arduino combiner" superClass="it.baeyens.arduino.tool.combine"/>
<tool id="it.baeyens.arduino.tool.objcopy.eep.1423908465" name="Arduino tool Create eeprom" superClass="it.baeyens.arduino.tool.objcopy.eep"/>
<tool id="it.baeyens.arduino.tool.objcopy.flash.1353974236" name="Arduino tool Create hex" superClass="it.baeyens.arduino.tool.objcopy.flash"/>
<tool id="it.baeyens.arduino.tool.size.1236092486" name="Arduino tool Print Size" superClass="it.baeyens.arduino.tool.size"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="LiquidCrystal|WiFi|SPI|Libraries/*/?xamples|Libraries/*/?xtras" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="LiquidCrystal"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="SPI"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="WiFi"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="WiModbusGateway.null.639869919" name="WiModbusGateway"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope"/>
</cproject>

54
.project Normal file
View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>WiModbusGateway</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
<nature>it.baeyens.arduinonature</nature>
</natures>
<linkedResources>
<link>
<name>arduino/core</name>
<type>2</type>
<locationURI>ArduinoPlatformPath/cores/arduino</locationURI>
</link>
<link>
<name>arduino/variant</name>
<type>2</type>
<locationURI>ArduinoPinPath/mega</locationURI>
</link>
</linkedResources>
<variableList>
<variable>
<name>ArduinoHardwareLibPath</name>
<value>file:/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/libraries</value>
</variable>
<variable>
<name>ArduinoPinPath</name>
<value>file:/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/variants</value>
</variable>
<variable>
<name>ArduinoPlatformPath</name>
<value>file:/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr</value>
</variable>
</variableList>
</projectDescription>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="it.baeyens.arduino.core.toolChain.release.1600398586" name="Release">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider class="it.baeyens.arduino.toolchain.ArduinoLanguageProvider" console="false" env-hash="-1803345556466996429" id="it.baeyens.arduino.languageSettingsProvider" keep-relative-paths="false" name="Arduino Compiler Settings" parameter="${COMMAND} -E -P -v -dD ${INPUTS}" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
</extension>
</configuration>
</project>

View File

@ -0,0 +1,399 @@
eclipse.preferences.version=1
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.ARCHITECTURE/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.ARCHITECTURE/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.ARCHITECTURE/value=avr
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.ARCHIVE_FILE/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.ARCHIVE_FILE/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.ARCHIVE_FILE/value=arduino.ar
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.EXTENDED_FUSES/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.EXTENDED_FUSES/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.EXTENDED_FUSES/value=0xFD
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.FILE/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.FILE/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.FILE/value=stk500v2/stk500boot_v2_mega2560.hex
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.HIGH_FUSES/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.HIGH_FUSES/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.HIGH_FUSES/value=0xD8
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.LOCK_BITS/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.LOCK_BITS/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.LOCK_BITS/value=0x0F
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.LOW_FUSES/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.LOW_FUSES/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.LOW_FUSES/value=0xFF
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.TOOL/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.TOOL/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.TOOL/value=avrdude
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.UNLOCK_BITS/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.UNLOCK_BITS/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BOOTLOADER.UNLOCK_BITS/value=0x3F
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.ARCH/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.ARCH/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.ARCH/value=AVR
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.BOARD/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.BOARD/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.BOARD/value=AVR_MEGA2560
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.CORE.PATH/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.CORE.PATH/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.CORE.PATH/value=${A.RUNTIME.PLATFORM.PATH}/cores/${A.BUILD.CORE}
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.CORE/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.CORE/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.CORE/value=arduino
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.EXTRA_FLAGS/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.EXTRA_FLAGS/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.EXTRA_FLAGS/value=
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.F_CPU/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.F_CPU/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.F_CPU/value=16000000L
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.MCU/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.MCU/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.MCU/value=atmega2560
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.PATH/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.PATH/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.PATH/value=${ProjDirPath}/${ConfigName}
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.PROJECT_NAME/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.PROJECT_NAME/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.PROJECT_NAME/value=${ProjName}
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.USB_FLAGS/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.USB_FLAGS/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.USB_FLAGS/value=-DUSB_VID\=${A.BUILD.VID} -DUSB_PID\=${A.BUILD.PID} '-DUSB_MANUFACTURER\=${A.BUILD.USB_MANUFACTURER}' '-DUSB_PRODUCT\=${A.BUILD.USB_PRODUCT}'
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.USB_MANUFACTURER/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.USB_MANUFACTURER/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.USB_MANUFACTURER/value="Unknown"
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.USE_ARCHIVER/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.USE_ARCHIVER/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.USE_ARCHIVER/value=true
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.VARIANT.PATH/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.VARIANT.PATH/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.VARIANT.PATH/value=${A.RUNTIME.PLATFORM.PATH}/variants/${A.BUILD.VARIANT}
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.VARIANT/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.VARIANT/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.BUILD.VARIANT/value=mega
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.CMD.PATH/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.CMD.PATH/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.CMD.PATH/value=${A.TOOLS.AVRDUDE.CMD.PATH}
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.CMD/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.CMD/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.CMD/value=${A.TOOLS.AVRDUDE.CMD}
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.AR.CMD/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.AR.CMD/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.AR.CMD/value=avr-ar
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.AR.EXTRA_FLAGS/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.AR.EXTRA_FLAGS/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.AR.EXTRA_FLAGS/value=
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.AR.FLAGS/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.AR.FLAGS/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.AR.FLAGS/value=rcs
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.C.CMD/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.C.CMD/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.C.CMD/value=avr-gcc
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.C.ELF.CMD/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.C.ELF.CMD/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.C.ELF.CMD/value=avr-gcc
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.C.ELF.EXTRA_FLAGS/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.C.ELF.EXTRA_FLAGS/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.C.ELF.EXTRA_FLAGS/value=
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.C.ELF.FLAGS/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.C.ELF.FLAGS/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.C.ELF.FLAGS/value=-w -Os -Wl,--gc-sections
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.C.EXTRA_FLAGS/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.C.EXTRA_FLAGS/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.C.EXTRA_FLAGS/value=
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.C.FLAGS/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.C.FLAGS/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.C.FLAGS/value=-c -g -Os -w -ffunction-sections -fdata-sections -MMD
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.CPP.CMD/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.CPP.CMD/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.CPP.CMD/value=avr-g++
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.CPP.EXTRA_FLAGS/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.CPP.EXTRA_FLAGS/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.CPP.EXTRA_FLAGS/value=
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.CPP.FLAGS/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.CPP.FLAGS/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.CPP.FLAGS/value=-c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.ELF2HEX.CMD/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.ELF2HEX.CMD/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.ELF2HEX.CMD/value=avr-objcopy
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.ELF2HEX.EXTRA_FLAGS/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.ELF2HEX.EXTRA_FLAGS/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.ELF2HEX.EXTRA_FLAGS/value=
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.ELF2HEX.FLAGS/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.ELF2HEX.FLAGS/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.ELF2HEX.FLAGS/value=-O ihex -R .eeprom
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.LDFLAGS/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.LDFLAGS/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.LDFLAGS/value=
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.OBJCOPY.CMD/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.OBJCOPY.CMD/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.OBJCOPY.CMD/value=avr-objcopy
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.OBJCOPY.EEP.EXTRA_FLAGS/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.OBJCOPY.EEP.EXTRA_FLAGS/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.OBJCOPY.EEP.EXTRA_FLAGS/value=
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.OBJCOPY.EEP.FLAGS/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.OBJCOPY.EEP.FLAGS/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.OBJCOPY.EEP.FLAGS/value=-O ihex -j .eeprom --set-section-flags\=.eeprom\=alloc,load --no-change-warnings --change-section-lma .eeprom\=0
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.PATH/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.PATH/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.PATH/value=${A.RUNTIME.IDE.PATH}/hardware/tools/avr/bin/
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.S.EXTRA_FLAGS/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.S.EXTRA_FLAGS/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.S.EXTRA_FLAGS/value=
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.S.FLAGS/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.S.FLAGS/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.S.FLAGS/value=-c -g -x assembler-with-cpp
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.SIZE.CMD/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.SIZE.CMD/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.COMPILER.SIZE.CMD/value=avr-size
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.CONFIG.PATH/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.CONFIG.PATH/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.CONFIG.PATH/value=${A.TOOLS.AVRDUDE.CONFIG.PATH}
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.DTS/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.DTS/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.DTS/value=3600
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.LOCAL/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.LOCAL/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.LOCAL/value=1430496628
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.UTC/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.UTC/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.UTC/value=1430489428
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.ZONE/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.ZONE/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.ZONE/value=3600
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.NAME/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.NAME/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.NAME/value=Arduino Mega or Mega 2560
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.PATH/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.PATH/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.PATH/value=${A.TOOLS.AVRDUDE.PATH}
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.PID.0/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.PID.0/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.PID.0/value=0x0010
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.PID.1/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.PID.1/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.PID.1/value=0x0042
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.PID.2/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.PID.2/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.PID.2/value=0x0010
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.PID.3/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.PID.3/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.PID.3/value=0x0042
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.AR.PATTERN.1/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.AR.PATTERN.1/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.AR.PATTERN.1/value="${A.COMPILER.PATH}${A.COMPILER.AR.CMD}" ${A.COMPILER.AR.FLAGS} ${A.COMPILER.AR.EXTRA_FLAGS} "${A.BUILD.PATH}/${A.ARCHIVE_FILE}"
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.AR.PATTERN.2/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.AR.PATTERN.2/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.AR.PATTERN.2/value=
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.AR.PATTERN/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.AR.PATTERN/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.AR.PATTERN/value="${A.COMPILER.PATH}${A.COMPILER.AR.CMD}" ${A.COMPILER.AR.FLAGS} ${A.COMPILER.AR.EXTRA_FLAGS} "${A.BUILD.PATH}/${A.ARCHIVE_FILE}" "${A.OBJECT_FILE}"
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.COMBINE.PATTERN.1/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.COMBINE.PATTERN.1/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.COMBINE.PATTERN.1/value="${A.COMPILER.PATH}${A.COMPILER.C.ELF.CMD}" ${A.COMPILER.C.ELF.FLAGS} -mmcu\=${A.BUILD.MCU} ${A.COMPILER.C.ELF.EXTRA_FLAGS} -o "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf"
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.COMBINE.PATTERN.2/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.COMBINE.PATTERN.2/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.COMBINE.PATTERN.2/value=\ "${A.BUILD.PATH}/${A.ARCHIVE_FILE}" "-L${A.BUILD.PATH}" -lm
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.COMBINE.PATTERN/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.COMBINE.PATTERN/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.COMBINE.PATTERN/value="${A.COMPILER.PATH}${A.COMPILER.C.ELF.CMD}" ${A.COMPILER.C.ELF.FLAGS} -mmcu\=${A.BUILD.MCU} ${A.COMPILER.C.ELF.EXTRA_FLAGS} -o "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf" ${A.OBJECT_FILES} "${A.BUILD.PATH}/${A.ARCHIVE_FILE}" "-L${A.BUILD.PATH}" -lm
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.O.PATTERN.1/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.O.PATTERN.1/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.O.PATTERN.1/value="${A.COMPILER.PATH}${A.COMPILER.C.CMD}" ${A.COMPILER.C.FLAGS} -mmcu\=${A.BUILD.MCU} -DF_CPU\=${A.BUILD.F_CPU} -DARDUINO\=${A.RUNTIME.IDE.VERSION} -DARDUINO_${A.BUILD.BOARD} -DARDUINO_ARCH_${A.BUILD.ARCH} ${A.COMPILER.C.EXTRA_FLAGS} ${A.BUILD.EXTRA_FLAGS} ${A.INCLUDES}
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.O.PATTERN.2/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.O.PATTERN.2/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.O.PATTERN.2/value=\ -o
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.O.PATTERN.3/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.O.PATTERN.3/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.O.PATTERN.3/value=
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.O.PATTERN/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.O.PATTERN/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.C.O.PATTERN/value="${A.COMPILER.PATH}${A.COMPILER.C.CMD}" ${A.COMPILER.C.FLAGS} -mmcu\=${A.BUILD.MCU} -DF_CPU\=${A.BUILD.F_CPU} -DARDUINO\=${A.RUNTIME.IDE.VERSION} -DARDUINO_${A.BUILD.BOARD} -DARDUINO_ARCH_${A.BUILD.ARCH} ${A.COMPILER.C.EXTRA_FLAGS} ${A.BUILD.EXTRA_FLAGS} ${A.INCLUDES} "${A.SOURCE_FILE}" -o "${A.OBJECT_FILE}"
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.CPP.O.PATTERN.1/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.CPP.O.PATTERN.1/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.CPP.O.PATTERN.1/value="${A.COMPILER.PATH}${A.COMPILER.CPP.CMD}" ${A.COMPILER.CPP.FLAGS} -mmcu\=${A.BUILD.MCU} -DF_CPU\=${A.BUILD.F_CPU} -DARDUINO\=${A.RUNTIME.IDE.VERSION} -DARDUINO_${A.BUILD.BOARD} -DARDUINO_ARCH_${A.BUILD.ARCH} ${A.COMPILER.CPP.EXTRA_FLAGS} ${A.BUILD.EXTRA_FLAGS} ${A.INCLUDES}
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.CPP.O.PATTERN.2/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.CPP.O.PATTERN.2/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.CPP.O.PATTERN.2/value=\ -o
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.CPP.O.PATTERN.3/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.CPP.O.PATTERN.3/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.CPP.O.PATTERN.3/value=
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.CPP.O.PATTERN/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.CPP.O.PATTERN/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.CPP.O.PATTERN/value="${A.COMPILER.PATH}${A.COMPILER.CPP.CMD}" ${A.COMPILER.CPP.FLAGS} -mmcu\=${A.BUILD.MCU} -DF_CPU\=${A.BUILD.F_CPU} -DARDUINO\=${A.RUNTIME.IDE.VERSION} -DARDUINO_${A.BUILD.BOARD} -DARDUINO_ARCH_${A.BUILD.ARCH} ${A.COMPILER.CPP.EXTRA_FLAGS} ${A.BUILD.EXTRA_FLAGS} ${A.INCLUDES} "${A.SOURCE_FILE}" -o "${A.OBJECT_FILE}"
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.OBJCOPY.EEP.PATTERN.1/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.OBJCOPY.EEP.PATTERN.1/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.OBJCOPY.EEP.PATTERN.1/value="${A.COMPILER.PATH}${A.COMPILER.OBJCOPY.CMD}" ${A.COMPILER.OBJCOPY.EEP.FLAGS} ${A.COMPILER.OBJCOPY.EEP.EXTRA_FLAGS} "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf" "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.eep"
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.OBJCOPY.EEP.PATTERN/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.OBJCOPY.EEP.PATTERN/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.OBJCOPY.EEP.PATTERN/value="${A.COMPILER.PATH}${A.COMPILER.OBJCOPY.CMD}" ${A.COMPILER.OBJCOPY.EEP.FLAGS} ${A.COMPILER.OBJCOPY.EEP.EXTRA_FLAGS} "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf" "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.eep"
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.OBJCOPY.HEX.PATTERN.1/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.OBJCOPY.HEX.PATTERN.1/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.OBJCOPY.HEX.PATTERN.1/value="${A.COMPILER.PATH}${A.COMPILER.ELF2HEX.CMD}" ${A.COMPILER.ELF2HEX.FLAGS} ${A.COMPILER.ELF2HEX.EXTRA_FLAGS} "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf" "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.hex"
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.OBJCOPY.HEX.PATTERN/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.OBJCOPY.HEX.PATTERN/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.OBJCOPY.HEX.PATTERN/value="${A.COMPILER.PATH}${A.COMPILER.ELF2HEX.CMD}" ${A.COMPILER.ELF2HEX.FLAGS} ${A.COMPILER.ELF2HEX.EXTRA_FLAGS} "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf" "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.hex"
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.S.O.PATTERN.1/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.S.O.PATTERN.1/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.S.O.PATTERN.1/value="${A.COMPILER.PATH}${A.COMPILER.C.CMD}" ${A.COMPILER.S.FLAGS} -mmcu\=${A.BUILD.MCU} -DF_CPU\=${A.BUILD.F_CPU} -DARDUINO\=${A.RUNTIME.IDE.VERSION} -DARDUINO_${A.BUILD.BOARD} -DARDUINO_ARCH_${A.BUILD.ARCH} ${A.COMPILER.S.EXTRA_FLAGS} ${A.BUILD.EXTRA_FLAGS} ${A.INCLUDES}
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.S.O.PATTERN.2/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.S.O.PATTERN.2/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.S.O.PATTERN.2/value=\ -o
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.S.O.PATTERN.3/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.S.O.PATTERN.3/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.S.O.PATTERN.3/value=
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.S.O.PATTERN/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.S.O.PATTERN/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.S.O.PATTERN/value="${A.COMPILER.PATH}${A.COMPILER.C.CMD}" ${A.COMPILER.S.FLAGS} -mmcu\=${A.BUILD.MCU} -DF_CPU\=${A.BUILD.F_CPU} -DARDUINO\=${A.RUNTIME.IDE.VERSION} -DARDUINO_${A.BUILD.BOARD} -DARDUINO_ARCH_${A.BUILD.ARCH} ${A.COMPILER.S.EXTRA_FLAGS} ${A.BUILD.EXTRA_FLAGS} ${A.INCLUDES} "${A.SOURCE_FILE}" -o "${A.OBJECT_FILE}"
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.SIZE.PATTERN.1/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.SIZE.PATTERN.1/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.SIZE.PATTERN.1/value="${A.COMPILER.PATH}${A.COMPILER.SIZE.CMD}" -A "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf"
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.SIZE.PATTERN/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.SIZE.PATTERN/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.SIZE.PATTERN/value="${A.COMPILER.PATH}${A.COMPILER.SIZE.CMD}" -A "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf"
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.SIZE.REGEX.DATA/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.SIZE.REGEX.DATA/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.SIZE.REGEX.DATA/value=^(?\:\\.data|\\.bss|\\.noinit)\\s+([0-9]+).*
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.SIZE.REGEX.EEPROM/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.SIZE.REGEX.EEPROM/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.SIZE.REGEX.EEPROM/value=^(?\:\\.eeprom)\\s+([0-9]+).*
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.SIZE.REGEX/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.SIZE.REGEX/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RECIPE.SIZE.REGEX/value=^(?\:\\.text|\\.data|\\.bootloader)\\s+([0-9]+).*
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RUNTIME.HARDWARE.PATH/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RUNTIME.HARDWARE.PATH/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RUNTIME.HARDWARE.PATH/value=/Applications/Arduino.app/Contents/Resources/Java/hardware
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RUNTIME.IDE.PATH/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RUNTIME.IDE.PATH/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RUNTIME.IDE.PATH/value=/Applications/Arduino.app/Contents/Resources/Java
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RUNTIME.IDE.VERSION/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RUNTIME.IDE.VERSION/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RUNTIME.IDE.VERSION/value=161
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RUNTIME.PLATFORM.PATH/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RUNTIME.PLATFORM.PATH/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.RUNTIME.PLATFORM.PATH/value=/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.SOFTWARE/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.SOFTWARE/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.SOFTWARE/value=ARDUINO
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.BOOTLOADER.PARAMS.QUIET/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.BOOTLOADER.PARAMS.QUIET/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.BOOTLOADER.PARAMS.QUIET/value=-q -q
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.BOOTLOADER.PARAMS.VERBOSE/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.BOOTLOADER.PARAMS.VERBOSE/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.BOOTLOADER.PARAMS.VERBOSE/value=-v
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.BOOTLOADER.PATTERN/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.BOOTLOADER.PATTERN/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.BOOTLOADER.PATTERN/value="${A.CMD.PATH}" "-C${A.CONFIG.PATH}" ${A.BOOTLOADER.VERBOSE} -p${A.BUILD.MCU} -c${A.PROTOCOL} ${A.PROGRAM.EXTRA_PARAMS} "-Uflash\:w\:${A.RUNTIME.PLATFORM.PATH}/bootloaders/${A.BOOTLOADER.FILE}\:i" -Ulock\:w\:${A.BOOTLOADER.LOCK_BITS}\:m
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.CMD.PATH/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.CMD.PATH/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.CMD.PATH/value=${A.RUNTIME.IDE.PATH}/hardware/tools/avr/bin/avrdude
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.CONFIG.PATH/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.CONFIG.PATH/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.CONFIG.PATH/value=${A.RUNTIME.IDE.PATH}/hardware/tools/avr/etc/avrdude.conf
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.ERASE.PARAMS.QUIET/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.ERASE.PARAMS.QUIET/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.ERASE.PARAMS.QUIET/value=-q -q
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.ERASE.PARAMS.VERBOSE/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.ERASE.PARAMS.VERBOSE/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.ERASE.PARAMS.VERBOSE/value=-v
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.ERASE.PATTERN/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.ERASE.PATTERN/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.ERASE.PATTERN/value="${A.CMD.PATH}" "-C${A.CONFIG.PATH}" ${A.ERASE.VERBOSE} -p${A.BUILD.MCU} -c${A.PROTOCOL} ${A.PROGRAM.EXTRA_PARAMS} -e -Ulock\:w\:${A.BOOTLOADER.UNLOCK_BITS}\:m -Uefuse\:w\:${A.BOOTLOADER.EXTENDED_FUSES}\:m -Uhfuse\:w\:${A.BOOTLOADER.HIGH_FUSES}\:m -Ulfuse\:w\:${A.BOOTLOADER.LOW_FUSES}\:m
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.PROGRAM.PARAMS.QUIET/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.PROGRAM.PARAMS.QUIET/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.PROGRAM.PARAMS.QUIET/value=-q -q
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.PROGRAM.PARAMS.VERBOSE/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.PROGRAM.PARAMS.VERBOSE/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.PROGRAM.PARAMS.VERBOSE/value=-v
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.PROGRAM.PATTERN/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.PROGRAM.PATTERN/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.PROGRAM.PATTERN/value="${A.CMD.PATH}" "-C${A.CONFIG.PATH}" ${A.PROGRAM.VERBOSE} -p${A.BUILD.MCU} -c${A.PROTOCOL} ${A.PROGRAM.EXTRA_PARAMS} "-Uflash\:w\:${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.hex\:i"
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.UPLOAD.PARAMS.QUIET/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.UPLOAD.PARAMS.QUIET/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.UPLOAD.PARAMS.QUIET/value=-q -q
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.UPLOAD.PARAMS.VERBOSE/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.UPLOAD.PARAMS.VERBOSE/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.UPLOAD.PARAMS.VERBOSE/value=-v
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.UPLOAD.PATTERN/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.UPLOAD.PATTERN/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.TOOLS.AVRDUDE.UPLOAD.PATTERN/value="${A.CMD.PATH}" "-C${A.CONFIG.PATH}" ${A.UPLOAD.VERBOSE} -p${A.BUILD.MCU} -c${A.UPLOAD.PROTOCOL} -P${A.SERIAL.PORT} -b${A.UPLOAD.SPEED} -D "-Uflash\:w\:${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.hex\:i"
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.UPLOAD.MAXIMUM_DATA_SIZE/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.UPLOAD.MAXIMUM_DATA_SIZE/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.UPLOAD.MAXIMUM_DATA_SIZE/value=8192
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.UPLOAD.MAXIMUM_SIZE/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.UPLOAD.MAXIMUM_SIZE/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.UPLOAD.MAXIMUM_SIZE/value=253952
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.UPLOAD.PROTOCOL/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.UPLOAD.PROTOCOL/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.UPLOAD.PROTOCOL/value=wiring
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.UPLOAD.SPEED/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.UPLOAD.SPEED/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.UPLOAD.SPEED/value=115200
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.UPLOAD.TOOL/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.UPLOAD.TOOL/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.UPLOAD.TOOL/value=avrdude
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.VERSION/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.VERSION/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.VERSION/value=1.6.1
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.VID.0/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.VID.0/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.VID.0/value=0x2341
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.VID.0X2A03.WARNING/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.VID.0X2A03.WARNING/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.VID.0X2A03.WARNING/value=Uncertified
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.VID.1/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.VID.1/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.VID.1/value=0x2341
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.VID.2/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.VID.2/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.VID.2/value=0x2A03
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.VID.3/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.VID.3/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.VID.3/value=0x2A03
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.BOARDS_FILE/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.BOARDS_FILE/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.BOARDS_FILE/value=/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/boards.txt
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.BOARD_NAME/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.BOARD_NAME/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.BOARD_NAME/value=Arduino Mega or Mega 2560
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.COM_PORT/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.COM_PORT/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.COM_PORT/value=/dev/tty.usbmodemfa131
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.COM_PROGMR/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.COM_PROGMR/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.COM_PROGMR/value=Default
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.CPU\ Speed/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.CPU\ Speed/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.CPU\ Speed/value=
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.EXTRA.C.COMPILE/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.EXTRA.C.COMPILE/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.EXTRA.C.COMPILE/value=
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.EXTRA.COMPILE/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.EXTRA.COMPILE/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.EXTRA.COMPILE/value=
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.EXTRA.CPP.COMPILE/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.EXTRA.CPP.COMPILE/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.EXTRA.CPP.COMPILE/value=
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.Keyboard\ Layout/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.Keyboard\ Layout/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.Keyboard\ Layout/value=
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.PLATFORM_FILE/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.PLATFORM_FILE/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.PLATFORM_FILE/value=/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/platform.txt
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.Processor/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.Processor/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.Processor/value=ATmega2560 (Mega 2560)
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.SIZE.SWITCH/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.SIZE.SWITCH/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.SIZE.SWITCH/value=${A.RECIPE.SIZE.PATTERN}
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.SIZE_COMMAND/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.SIZE_COMMAND/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.SIZE_COMMAND/value="${A.COMPILER.PATH}${A.COMPILER.SIZE.CMD}" --format\=avr --mcu\=${A.BUILD.MCU} "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf"
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.USB\ Type/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.USB\ Type/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.USB\ Type/value=
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.WARNING_LEVEL/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.WARNING_LEVEL/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.WARNING_LEVEL/value=\ -Wall
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/PATH/delimiter=\:
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/PATH/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/PATH/value=${A.COMPILER.PATH}${PathDelimiter}${A.BUILD.GENERIC.PATH}${PathDelimiter}${PATH}
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/append=true
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/appendContributed=true

View File

@ -0,0 +1,322 @@
#include "LiquidCrystal.h"
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "Arduino.h"
// When the display powers up, it is configured as follows:
//
// 1. Display clear
// 2. Function set:
// DL = 1; 8-bit interface data
// N = 0; 1-line display
// F = 0; 5x8 dot character font
// 3. Display on/off control:
// D = 0; Display off
// C = 0; Cursor off
// B = 0; Blinking off
// 4. Entry mode set:
// I/D = 1; Increment by 1
// S = 0; No shift
//
// Note, however, that resetting the Arduino doesn't reset the LCD, so we
// can't assume that its in that state when a sketch starts (and the
// LiquidCrystal constructor is called).
LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
{
init(0, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7);
}
LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
{
init(0, rs, 255, enable, d0, d1, d2, d3, d4, d5, d6, d7);
}
LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3)
{
init(1, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0);
}
LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3)
{
init(1, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0);
}
void LiquidCrystal::init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
{
_rs_pin = rs;
_rw_pin = rw;
_enable_pin = enable;
_data_pins[0] = d0;
_data_pins[1] = d1;
_data_pins[2] = d2;
_data_pins[3] = d3;
_data_pins[4] = d4;
_data_pins[5] = d5;
_data_pins[6] = d6;
_data_pins[7] = d7;
pinMode(_rs_pin, OUTPUT);
// we can save 1 pin by not using RW. Indicate by passing 255 instead of pin#
if (_rw_pin != 255) {
pinMode(_rw_pin, OUTPUT);
}
pinMode(_enable_pin, OUTPUT);
if (fourbitmode)
_displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
else
_displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS;
begin(16, 1);
}
void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
if (lines > 1) {
_displayfunction |= LCD_2LINE;
}
_numlines = lines;
setRowOffsets(0x00, 0x40, 0x00 + cols, 0x40 + cols);
// for some 1 line displays you can select a 10 pixel high font
if ((dotsize != LCD_5x8DOTS) && (lines == 1)) {
_displayfunction |= LCD_5x10DOTS;
}
// SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
// according to datasheet, we need at least 40ms after power rises above 2.7V
// before sending commands. Arduino can turn on way before 4.5V so we'll wait 50
delayMicroseconds(50000);
// Now we pull both RS and R/W low to begin commands
digitalWrite(_rs_pin, LOW);
digitalWrite(_enable_pin, LOW);
if (_rw_pin != 255) {
digitalWrite(_rw_pin, LOW);
}
//put the LCD into 4 bit or 8 bit mode
if (! (_displayfunction & LCD_8BITMODE)) {
// this is according to the hitachi HD44780 datasheet
// figure 24, pg 46
// we start in 8bit mode, try to set 4 bit mode
write4bits(0x03);
delayMicroseconds(4500); // wait min 4.1ms
// second try
write4bits(0x03);
delayMicroseconds(4500); // wait min 4.1ms
// third go!
write4bits(0x03);
delayMicroseconds(150);
// finally, set to 4-bit interface
write4bits(0x02);
} else {
// this is according to the hitachi HD44780 datasheet
// page 45 figure 23
// Send function set command sequence
command(LCD_FUNCTIONSET | _displayfunction);
delayMicroseconds(4500); // wait more than 4.1ms
// second try
command(LCD_FUNCTIONSET | _displayfunction);
delayMicroseconds(150);
// third go
command(LCD_FUNCTIONSET | _displayfunction);
}
// finally, set # lines, font size, etc.
command(LCD_FUNCTIONSET | _displayfunction);
// turn the display on with no cursor or blinking default
_displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
display();
// clear it off
clear();
// Initialize to default text direction (for romance languages)
_displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
// set the entry mode
command(LCD_ENTRYMODESET | _displaymode);
}
void LiquidCrystal::setRowOffsets(int row0, int row1, int row2, int row3)
{
_row_offsets[0] = row0;
_row_offsets[1] = row1;
_row_offsets[2] = row2;
_row_offsets[3] = row3;
}
/********** high level commands, for the user! */
void LiquidCrystal::clear()
{
command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero
delayMicroseconds(2000); // this command takes a long time!
}
void LiquidCrystal::home()
{
command(LCD_RETURNHOME); // set cursor position to zero
delayMicroseconds(2000); // this command takes a long time!
}
void LiquidCrystal::setCursor(uint8_t col, uint8_t row)
{
const size_t max_lines = sizeof(_row_offsets) / sizeof(*_row_offsets);
if ( row >= max_lines ) {
row = max_lines - 1; // we count rows starting w/0
}
if ( row >= _numlines ) {
row = _numlines - 1; // we count rows starting w/0
}
command(LCD_SETDDRAMADDR | (col + _row_offsets[row]));
}
// Turn the display on/off (quickly)
void LiquidCrystal::noDisplay() {
_displaycontrol &= ~LCD_DISPLAYON;
command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void LiquidCrystal::display() {
_displaycontrol |= LCD_DISPLAYON;
command(LCD_DISPLAYCONTROL | _displaycontrol);
}
// Turns the underline cursor on/off
void LiquidCrystal::noCursor() {
_displaycontrol &= ~LCD_CURSORON;
command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void LiquidCrystal::cursor() {
_displaycontrol |= LCD_CURSORON;
command(LCD_DISPLAYCONTROL | _displaycontrol);
}
// Turn on and off the blinking cursor
void LiquidCrystal::noBlink() {
_displaycontrol &= ~LCD_BLINKON;
command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void LiquidCrystal::blink() {
_displaycontrol |= LCD_BLINKON;
command(LCD_DISPLAYCONTROL | _displaycontrol);
}
// These commands scroll the display without changing the RAM
void LiquidCrystal::scrollDisplayLeft(void) {
command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
}
void LiquidCrystal::scrollDisplayRight(void) {
command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
}
// This is for text that flows Left to Right
void LiquidCrystal::leftToRight(void) {
_displaymode |= LCD_ENTRYLEFT;
command(LCD_ENTRYMODESET | _displaymode);
}
// This is for text that flows Right to Left
void LiquidCrystal::rightToLeft(void) {
_displaymode &= ~LCD_ENTRYLEFT;
command(LCD_ENTRYMODESET | _displaymode);
}
// This will 'right justify' text from the cursor
void LiquidCrystal::autoscroll(void) {
_displaymode |= LCD_ENTRYSHIFTINCREMENT;
command(LCD_ENTRYMODESET | _displaymode);
}
// This will 'left justify' text from the cursor
void LiquidCrystal::noAutoscroll(void) {
_displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
command(LCD_ENTRYMODESET | _displaymode);
}
// Allows us to fill the first 8 CGRAM locations
// with custom characters
void LiquidCrystal::createChar(uint8_t location, uint8_t charmap[]) {
location &= 0x7; // we only have 8 locations 0-7
command(LCD_SETCGRAMADDR | (location << 3));
for (int i=0; i<8; i++) {
write(charmap[i]);
}
}
/*********** mid level commands, for sending data/cmds */
inline void LiquidCrystal::command(uint8_t value) {
send(value, LOW);
}
inline size_t LiquidCrystal::write(uint8_t value) {
send(value, HIGH);
return 1; // assume sucess
}
/************ low level data pushing commands **********/
// write either command or data, with automatic 4/8-bit selection
void LiquidCrystal::send(uint8_t value, uint8_t mode) {
digitalWrite(_rs_pin, mode);
// if there is a RW pin indicated, set it low to Write
if (_rw_pin != 255) {
digitalWrite(_rw_pin, LOW);
}
if (_displayfunction & LCD_8BITMODE) {
write8bits(value);
} else {
write4bits(value>>4);
write4bits(value);
}
}
void LiquidCrystal::pulseEnable(void) {
digitalWrite(_enable_pin, LOW);
delayMicroseconds(1);
digitalWrite(_enable_pin, HIGH);
delayMicroseconds(1); // enable pulse must be >450ns
digitalWrite(_enable_pin, LOW);
delayMicroseconds(100); // commands need > 37us to settle
}
void LiquidCrystal::write4bits(uint8_t value) {
for (int i = 0; i < 4; i++) {
pinMode(_data_pins[i], OUTPUT);
digitalWrite(_data_pins[i], (value >> i) & 0x01);
}
pulseEnable();
}
void LiquidCrystal::write8bits(uint8_t value) {
for (int i = 0; i < 8; i++) {
pinMode(_data_pins[i], OUTPUT);
digitalWrite(_data_pins[i], (value >> i) & 0x01);
}
pulseEnable();
}

View File

@ -0,0 +1,108 @@
#ifndef LiquidCrystal_h
#define LiquidCrystal_h
#include <inttypes.h>
#include "Print.h"
// commands
#define LCD_CLEARDISPLAY 0x01
#define LCD_RETURNHOME 0x02
#define LCD_ENTRYMODESET 0x04
#define LCD_DISPLAYCONTROL 0x08
#define LCD_CURSORSHIFT 0x10
#define LCD_FUNCTIONSET 0x20
#define LCD_SETCGRAMADDR 0x40
#define LCD_SETDDRAMADDR 0x80
// flags for display entry mode
#define LCD_ENTRYRIGHT 0x00
#define LCD_ENTRYLEFT 0x02
#define LCD_ENTRYSHIFTINCREMENT 0x01
#define LCD_ENTRYSHIFTDECREMENT 0x00
// flags for display on/off control
#define LCD_DISPLAYON 0x04
#define LCD_DISPLAYOFF 0x00
#define LCD_CURSORON 0x02
#define LCD_CURSOROFF 0x00
#define LCD_BLINKON 0x01
#define LCD_BLINKOFF 0x00
// flags for display/cursor shift
#define LCD_DISPLAYMOVE 0x08
#define LCD_CURSORMOVE 0x00
#define LCD_MOVERIGHT 0x04
#define LCD_MOVELEFT 0x00
// flags for function set
#define LCD_8BITMODE 0x10
#define LCD_4BITMODE 0x00
#define LCD_2LINE 0x08
#define LCD_1LINE 0x00
#define LCD_5x10DOTS 0x04
#define LCD_5x8DOTS 0x00
class LiquidCrystal : public Print {
public:
LiquidCrystal(uint8_t rs, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);
LiquidCrystal(uint8_t rs, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);
void init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS);
void clear();
void home();
void noDisplay();
void display();
void noBlink();
void blink();
void noCursor();
void cursor();
void scrollDisplayLeft();
void scrollDisplayRight();
void leftToRight();
void rightToLeft();
void autoscroll();
void noAutoscroll();
void setRowOffsets(int row1, int row2, int row3, int row4);
void createChar(uint8_t, uint8_t[]);
void setCursor(uint8_t, uint8_t);
virtual size_t write(uint8_t);
void command(uint8_t);
using Print::write;
private:
void send(uint8_t, uint8_t);
void write4bits(uint8_t);
void write8bits(uint8_t);
void pulseEnable();
uint8_t _rs_pin; // LOW: command. HIGH: character.
uint8_t _rw_pin; // LOW: write to LCD. HIGH: read from LCD.
uint8_t _enable_pin; // activated by a HIGH pulse.
uint8_t _data_pins[8];
uint8_t _displayfunction;
uint8_t _displaycontrol;
uint8_t _displaymode;
uint8_t _initialized;
uint8_t _numlines;
uint8_t _row_offsets[4];
};
#endif

73
Metro.cpp Normal file
View File

@ -0,0 +1,73 @@
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include "Metro.h"
Metro::Metro(unsigned long interval_millis)
{
this->autoreset = 0;
interval(interval_millis);
reset();
}
// New creator so I can use either the original check behavior or benjamin.soelberg's
// suggested one (see below).
// autoreset = 0 is benjamin.soelberg's check behavior
// autoreset != 0 is the original behavior
Metro::Metro(unsigned long interval_millis, uint8_t autoreset)
{
this->autoreset = autoreset; // Fix by Paul Bouchier
interval(interval_millis);
reset();
}
void Metro::interval(unsigned long interval_millis)
{
this->interval_millis = interval_millis;
}
// Benjamin.soelberg's check behavior:
// When a check is true, add the interval to the internal counter.
// This should guarantee a better overall stability.
// Original check behavior:
// When a check is true, add the interval to the current millis() counter.
// This method can add a certain offset over time.
char Metro::check()
{
if (millis() - this->previous_millis >= this->interval_millis) {
// As suggested by benjamin.soelberg@gmail.com, the following line
// this->previous_millis = millis();
// was changed to
// this->previous_millis += this->interval_millis;
// If the interval is set to 0 we revert to the original behavior
if (this->interval_millis <= 0 || this->autoreset ) {
this->previous_millis = millis();
} else {
this->previous_millis += this->interval_millis;
}
return 1;
}
return 0;
}
void Metro::reset()
{
this->previous_millis = millis();
}

26
Metro.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef Metro_h
#define Metro_h
#include <inttypes.h>
class Metro
{
public:
Metro(unsigned long interval_millis);
Metro(unsigned long interval_millis, uint8_t autoreset);
void interval(unsigned long interval_millis);
char check();
void reset();
private:
uint8_t autoreset;
unsigned long previous_millis, interval_millis;
};
#endif

93
ModbusApp.cpp Normal file
View File

@ -0,0 +1,93 @@
/*
* ModbusApp.cpp
*
* Created on: 01.05.2015
* Author: wn
*/
#include "SimpleModbusMaster.h"
#include "Mudbus.h"
#include "ModbusApp.h"
enum
{
VOLTAGE,
FREQUENCY,
CURRENT,
POWER,
ENERGY,
TOTAL_NO_OF_PACKETS
};
Packet packets[TOTAL_NO_OF_PACKETS];
Mudbus *modbusSlave;
uint16_t voltage[2];
uint16_t frequency[2];
uint16_t current[2];
uint16_t power[2];
uint16_t energy[2];
float startEnergy = 0;
float convF(uint16_t in[2]) {
union {
struct {
uint16_t a;
uint16_t b;
} s;
float f;
} U;
U.s.a = in[1];
U.s.b = in[0];
return U.f;
}
float getVoltage() { return convF(voltage); }
float getCurrent() { return convF(current); }
float getFrequency() { return convF(frequency); }
float getPower() { return convF(power); }
float getEnergy() { return convF(energy); }
float getNewEnergy() { return convF(energy) - startEnergy; }
void modbusAppBegin(Mudbus *mb) {
pinMode(ZEROING_PIN, INPUT_PULLUP);
modbusSlave = mb;
modbus_construct(&packets[VOLTAGE], 1, READ_HOLDING_REGISTERS, 0x2000, 2, voltage);
modbus_construct(&packets[FREQUENCY], 1, READ_HOLDING_REGISTERS, 0x2020, 2, frequency);
modbus_construct(&packets[CURRENT], 1, READ_HOLDING_REGISTERS, 0x2060, 2, current);
modbus_construct(&packets[POWER], 1, READ_HOLDING_REGISTERS, 0x2080, 2, power);
modbus_construct(&packets[ENERGY], 1, READ_HOLDING_REGISTERS, 0x3000, 2, energy);
modbus_configure(&Serial2, MODBUS_BAUD, SERIAL_8N2, MODBUS_TIMEOUT,
MODBUS_SCANRATE, MODBUS_RETRY_COUNT, MODBUS_TX_ENABLE_PIN, packets, TOTAL_NO_OF_PACKETS);
}
void modbusAppExec() {
modbus_update();
float nEnergy = getEnergy();
if (((0 == startEnergy) && (0 != nEnergy)) || (digitalRead(ZEROING_PIN) == 0)) {
startEnergy = nEnergy;
}
modbusSlave->R[0] = voltage[0];
modbusSlave->R[1] = voltage[1];
modbusSlave->R[2] = current[0];
modbusSlave->R[3] = current[1];
modbusSlave->R[4] = frequency[0];
modbusSlave->R[5] = frequency[1];
modbusSlave->R[6] = power[0];
modbusSlave->R[7] = power[1];
modbusSlave->R[8] = energy[0];
modbusSlave->R[9] = energy[1];
}

37
ModbusApp.h Normal file
View File

@ -0,0 +1,37 @@
/*
* ModbusApp.h
*
* Created on: 01.05.2015
* Author: wn
*/
#ifndef MODBUSAPP_H_
#define MODBUSAPP_H_
#include "SimpleModbusMaster.h"
#include "Mudbus.h"
const uint32_t MODBUS_BAUD = 1200;
const uint16_t MODBUS_TIMEOUT = 10000;
const uint16_t MODBUS_SCANRATE = 1000;
const uint8_t MODBUS_RETRY_COUNT = 25;
const uint8_t MODBUS_TX_ENABLE_PIN = 2;
const uint8_t ZEROING_PIN = 3;
void modbusAppBegin(Mudbus *mb);
void modbusAppExec();
float getVoltage();
float getCurrent();
float getFrequency();
float getPower();
float getEnergy();
float getNewEnergy();
#endif /* MODBUSAPP_H_ */

245
Mudbus.cpp Normal file
View File

@ -0,0 +1,245 @@
/*
Mudbus.cpp - an Arduino library for a Modbus TCP slave.
Copyright (C) 2011 Dee Wykoff
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Mudbus.h"
// For Arduino 0022
// Server MbServer(MB_PORT);
// For Arduino 1.0
WiFiServer MbServer = WiFiServer(MB_PORT);
Mudbus::Mudbus()
{
}
void Mudbus::Run()
{
static bool serverStarted = false;
if (! serverStarted) {
MbServer.begin();
Serial.println("Modbus server started.");
serverStarted = true;
}
Runs = 1 + Runs * (Runs < 999);
//****************** Read from socket ****************
// For Arduino 0022
// Client client = MbServer.available();
// For Arduino 1.0
WiFiClient client = MbServer.available();
if(client.available())
{
Reads = 1 + Reads * (Reads < 999);
int i = 0;
while(client.available())
{
ByteArray[i] = client.read();
i++;
// Serial.println("read something from net");
}
SetFC(ByteArray[7]); //Byte 7 of request is FC
if(!Active)
{
Active = true;
PreviousActivityTime = millis();
#ifdef MbDebug
Serial.println("Mb active");
#endif
}
}
if(millis() > (PreviousActivityTime + 60000))
{
if(Active)
{
Active = false;
#ifdef MbDebug
Serial.println("Mb not active");
#endif
}
}
int Start, WordDataLength, ByteDataLength, CoilDataLength, MessageLength;
//****************** Read Coils **********************
if(FC == MB_FC_READ_COILS)
{
Start = word(ByteArray[8],ByteArray[9]);
CoilDataLength = word(ByteArray[10],ByteArray[11]);
ByteDataLength = CoilDataLength / 8;
if(ByteDataLength * 8 < CoilDataLength) ByteDataLength++;
CoilDataLength = ByteDataLength * 8;
#ifdef MbDebug
Serial.print(" MB_FC_READ_COILS S=");
Serial.print(Start);
Serial.print(" L=");
Serial.println(CoilDataLength);
#endif
ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one.
ByteArray[8] = ByteDataLength; //Number of bytes after this one (or number of bytes of data).
for(int i = 0; i < ByteDataLength ; i++)
{
for(int j = 0; j < 8; j++)
{
bitWrite(ByteArray[9 + i], j, C[Start + i * 8 + j]);
}
}
MessageLength = ByteDataLength + 9;
client.write(ByteArray, MessageLength);
Writes = 1 + Writes * (Writes < 999);
FC = MB_FC_NONE;
}
//****************** Read Registers ******************
if(FC == MB_FC_READ_REGISTERS)
{
Start = word(ByteArray[8],ByteArray[9]);
WordDataLength = word(ByteArray[10],ByteArray[11]);
ByteDataLength = WordDataLength * 2;
#ifdef MbDebug
Serial.print(" MB_FC_READ_REGISTERS S=");
Serial.print(Start);
Serial.print(" L=");
Serial.println(WordDataLength);
#endif
ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one.
ByteArray[8] = ByteDataLength; //Number of bytes after this one (or number of bytes of data).
for(int i = 0; i < WordDataLength; i++)
{
ByteArray[ 9 + i * 2] = highByte(R[Start + i]);
ByteArray[10 + i * 2] = lowByte(R[Start + i]);
}
MessageLength = ByteDataLength + 9;
client.write(ByteArray, MessageLength);
Writes = 1 + Writes * (Writes < 999);
FC = MB_FC_NONE;
}
//****************** Write Coil **********************
if(FC == MB_FC_WRITE_COIL)
{
Start = word(ByteArray[8],ByteArray[9]);
C[Start] = word(ByteArray[10],ByteArray[11]) > 0;
#ifdef MbDebug
Serial.print(" MB_FC_WRITE_COIL C");
Serial.print(Start);
Serial.print("=");
Serial.println(C[Start]);
#endif
ByteArray[5] = 2; //Number of bytes after this one.
MessageLength = 8;
client.write(ByteArray, MessageLength);
Writes = 1 + Writes * (Writes < 999);
FC = MB_FC_NONE;
}
//****************** Write Register ******************
if(FC == MB_FC_WRITE_REGISTER)
{
Start = word(ByteArray[8],ByteArray[9]);
R[Start] = word(ByteArray[10],ByteArray[11]);
#ifdef MbDebug
Serial.print(" MB_FC_WRITE_REGISTER R");
Serial.print(Start);
Serial.print("=");
Serial.println(R[Start]);
#endif
ByteArray[5] = 6; //Number of bytes after this one.
MessageLength = 12;
client.write(ByteArray, MessageLength);
Writes = 1 + Writes * (Writes < 999);
FC = MB_FC_NONE;
}
//****************** Write Multiple Coils **********************
//Function codes 15 & 16 by Martin Pettersson http://siamect.com
if(FC == MB_FC_WRITE_MULTIPLE_COILS)
{
Start = word(ByteArray[8],ByteArray[9]);
CoilDataLength = word(ByteArray[10],ByteArray[11]);
ByteDataLength = CoilDataLength / 8;
if(ByteDataLength * 8 < CoilDataLength) ByteDataLength++;
CoilDataLength = ByteDataLength * 8;
#ifdef MbDebug
Serial.print(" MB_FC_WRITE_MULTIPLE_COILS S=");
Serial.print(Start);
Serial.print(" L=");
Serial.println(CoilDataLength);
#endif
ByteArray[5] = ByteDataLength + 5; //Number of bytes after this one.
for(int i = 0; i < ByteDataLength ; i++)
{
for(int j = 0; j < 8; j++)
{
C[Start + i * 8 + j] = bitRead( ByteArray[13 + i], j);
}
}
MessageLength = 12;
client.write(ByteArray, MessageLength);
Writes = 1 + Writes * (Writes < 999);
FC = MB_FC_NONE;
}
//****************** Write Multiple Registers ******************
//Function codes 15 & 16 by Martin Pettersson http://siamect.com
if(FC == MB_FC_WRITE_MULTIPLE_REGISTERS)
{
Start = word(ByteArray[8],ByteArray[9]);
WordDataLength = word(ByteArray[10],ByteArray[11]);
ByteDataLength = WordDataLength * 2;
#ifdef MbDebug
Serial.print(" MB_FC_READ_REGISTERS S=");
Serial.print(Start);
Serial.print(" L=");
Serial.println(WordDataLength);
#endif
ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one.
for(int i = 0; i < WordDataLength; i++)
{
R[Start + i] = word(ByteArray[ 13 + i * 2],ByteArray[14 + i * 2]);
}
MessageLength = 12;
client.write(ByteArray, MessageLength);
Writes = 1 + Writes * (Writes < 999);
FC = MB_FC_NONE;
}
#ifdef MbDebugX
Serial.print("Mb runs: ");
Serial.print(Runs);
Serial.print(" reads: ");
Serial.print(Reads);
Serial.print(" writes: ");
Serial.print(Writes);
Serial.println();
#endif
}
void Mudbus::SetFC(int fc)
{
if(fc == 1) FC = MB_FC_READ_COILS;
if(fc == 3) FC = MB_FC_READ_REGISTERS;
if(fc == 5) FC = MB_FC_WRITE_COIL;
if(fc == 6) FC = MB_FC_WRITE_REGISTER;
if(fc == 15) FC = MB_FC_WRITE_MULTIPLE_COILS;
if(fc == 16) FC = MB_FC_WRITE_MULTIPLE_REGISTERS;
}

96
Mudbus.h Normal file
View File

@ -0,0 +1,96 @@
/*
Mudbus.h - an Arduino library for a Modbus TCP slave.
Copyright (C) 2011 Dee Wykoff
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//#define MbDebug
// For Arduino 0022
// #include "WProgram.h"
// For Arduino 1.0
#include "Arduino.h"
#include <SPI.h>
#include <WiFi.h>
#ifndef Mudbus_h
#define Mudbus_h
#define MbDebug
#define MB_N_R 125 //Max 16 bit registers for Modbus is 125
#define MB_N_C 128 //Max coils for Modbus is 2000 - dont need that many so here is a multiple of 8
#define MB_PORT 502
enum MB_FC {
MB_FC_NONE = 0,
MB_FC_READ_COILS = 1,
MB_FC_READ_REGISTERS = 3,
MB_FC_WRITE_COIL = 5,
MB_FC_WRITE_REGISTER = 6,
//Function codes 15 & 16 by Martin Pettersson http://siamect.com
MB_FC_WRITE_MULTIPLE_COILS = 15,
MB_FC_WRITE_MULTIPLE_REGISTERS = 16
};
class Mudbus
{
public:
Mudbus();
void Run();
int R[MB_N_R];
bool C[MB_N_C];
bool Active;
unsigned long PreviousActivityTime;
int Runs, Reads, Writes;
private:
uint8_t ByteArray[260];
MB_FC FC;
void SetFC(int fc);
};
#endif
/* Speculations on Modbus message structure:
**********************************************
**********Master(PC) request frames***********
00 ID high 0
01 ID low 1
02 Protocol high 0
03 Protocol low 0
04 Message length high 0
05 Message length low 6 (6 bytes after this)
06 Slave number 1
07 Function code
08 Start address high maybe 0
09 Start address low maybe 0
10 Length high maybe 125 or Data high if write
11 Length low maybe 125 or Data low if write
**********************************************
**********Slave(Arduino) response frames******
00 ID high echo / 0
01 ID low echo / slave ID 1
02 Protocol high echo
03 Protocol low echo
04 Message length high echo
05 Message length low num bytes after this
06 Slave number echo
07 Function code echo
08 Start address high num bytes of data
09 Data high
10 Data low
**********************************************
*/

193
SPI/SPI.cpp Normal file
View File

@ -0,0 +1,193 @@
/*
* Copyright (c) 2010 by Cristian Maglie <c.maglie@arduino.cc>
* Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
* Copyright (c) 2014 by Matthijs Kooijman <matthijs@stdin.nl> (SPISettings AVR)
* Copyright (c) 2014 by Andrew J. Kroll <xxxajk@gmail.com> (atomicity fixes)
* SPI Master library for arduino.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
#include "SPI.h"
SPIClass SPI;
uint8_t SPIClass::initialized = 0;
uint8_t SPIClass::interruptMode = 0;
uint8_t SPIClass::interruptMask = 0;
uint8_t SPIClass::interruptSave = 0;
#ifdef SPI_TRANSACTION_MISMATCH_LED
uint8_t SPIClass::inTransactionFlag = 0;
#endif
void SPIClass::begin()
{
uint8_t sreg = SREG;
noInterrupts(); // Protect from a scheduler and prevent transactionBegin
if (!initialized) {
// Set SS to high so a connected chip will be "deselected" by default
digitalWrite(SS, HIGH);
// When the SS pin is set as OUTPUT, it can be used as
// a general purpose output port (it doesn't influence
// SPI operations).
pinMode(SS, OUTPUT);
// Warning: if the SS pin ever becomes a LOW INPUT then SPI
// automatically switches to Slave, so the data direction of
// the SS pin MUST be kept as OUTPUT.
SPCR |= _BV(MSTR);
SPCR |= _BV(SPE);
// Set direction register for SCK and MOSI pin.
// MISO pin automatically overrides to INPUT.
// By doing this AFTER enabling SPI, we avoid accidentally
// clocking in a single bit since the lines go directly
// from "input" to SPI control.
// http://code.google.com/p/arduino/issues/detail?id=888
pinMode(SCK, OUTPUT);
pinMode(MOSI, OUTPUT);
}
initialized++; // reference count
SREG = sreg;
}
void SPIClass::end() {
uint8_t sreg = SREG;
noInterrupts(); // Protect from a scheduler and prevent transactionBegin
// Decrease the reference counter
if (initialized)
initialized--;
// If there are no more references disable SPI
if (!initialized) {
SPCR &= ~_BV(SPE);
interruptMode = 0;
#ifdef SPI_TRANSACTION_MISMATCH_LED
inTransactionFlag = 0;
#endif
}
SREG = sreg;
}
// mapping of interrupt numbers to bits within SPI_AVR_EIMSK
#if defined(__AVR_ATmega32U4__)
#define SPI_INT0_MASK (1<<INT0)
#define SPI_INT1_MASK (1<<INT1)
#define SPI_INT2_MASK (1<<INT2)
#define SPI_INT3_MASK (1<<INT3)
#define SPI_INT4_MASK (1<<INT6)
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
#define SPI_INT0_MASK (1<<INT0)
#define SPI_INT1_MASK (1<<INT1)
#define SPI_INT2_MASK (1<<INT2)
#define SPI_INT3_MASK (1<<INT3)
#define SPI_INT4_MASK (1<<INT4)
#define SPI_INT5_MASK (1<<INT5)
#define SPI_INT6_MASK (1<<INT6)
#define SPI_INT7_MASK (1<<INT7)
#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
#define SPI_INT0_MASK (1<<INT4)
#define SPI_INT1_MASK (1<<INT5)
#define SPI_INT2_MASK (1<<INT0)
#define SPI_INT3_MASK (1<<INT1)
#define SPI_INT4_MASK (1<<INT2)
#define SPI_INT5_MASK (1<<INT3)
#define SPI_INT6_MASK (1<<INT6)
#define SPI_INT7_MASK (1<<INT7)
#else
#ifdef INT0
#define SPI_INT0_MASK (1<<INT0)
#endif
#ifdef INT1
#define SPI_INT1_MASK (1<<INT1)
#endif
#ifdef INT2
#define SPI_INT2_MASK (1<<INT2)
#endif
#endif
void SPIClass::usingInterrupt(uint8_t interruptNumber)
{
uint8_t mask = 0;
uint8_t sreg = SREG;
noInterrupts(); // Protect from a scheduler and prevent transactionBegin
switch (interruptNumber) {
#ifdef SPI_INT0_MASK
case 0: mask = SPI_INT0_MASK; break;
#endif
#ifdef SPI_INT1_MASK
case 1: mask = SPI_INT1_MASK; break;
#endif
#ifdef SPI_INT2_MASK
case 2: mask = SPI_INT2_MASK; break;
#endif
#ifdef SPI_INT3_MASK
case 3: mask = SPI_INT3_MASK; break;
#endif
#ifdef SPI_INT4_MASK
case 4: mask = SPI_INT4_MASK; break;
#endif
#ifdef SPI_INT5_MASK
case 5: mask = SPI_INT5_MASK; break;
#endif
#ifdef SPI_INT6_MASK
case 6: mask = SPI_INT6_MASK; break;
#endif
#ifdef SPI_INT7_MASK
case 7: mask = SPI_INT7_MASK; break;
#endif
default:
interruptMode = 2;
break;
}
interruptMask |= mask;
if (!interruptMode)
interruptMode = 1;
SREG = sreg;
}
void SPIClass::notUsingInterrupt(uint8_t interruptNumber)
{
// Once in mode 2 we can't go back to 0 without a proper reference count
if (interruptMode == 2)
return;
uint8_t mask = 0;
uint8_t sreg = SREG;
noInterrupts(); // Protect from a scheduler and prevent transactionBegin
switch (interruptNumber) {
#ifdef SPI_INT0_MASK
case 0: mask = SPI_INT0_MASK; break;
#endif
#ifdef SPI_INT1_MASK
case 1: mask = SPI_INT1_MASK; break;
#endif
#ifdef SPI_INT2_MASK
case 2: mask = SPI_INT2_MASK; break;
#endif
#ifdef SPI_INT3_MASK
case 3: mask = SPI_INT3_MASK; break;
#endif
#ifdef SPI_INT4_MASK
case 4: mask = SPI_INT4_MASK; break;
#endif
#ifdef SPI_INT5_MASK
case 5: mask = SPI_INT5_MASK; break;
#endif
#ifdef SPI_INT6_MASK
case 6: mask = SPI_INT6_MASK; break;
#endif
#ifdef SPI_INT7_MASK
case 7: mask = SPI_INT7_MASK; break;
#endif
default:
break;
// this case can't be reached
}
interruptMask &= ~mask;
if (!interruptMask)
interruptMode = 0;
SREG = sreg;
}

324
SPI/SPI.h Normal file
View File

@ -0,0 +1,324 @@
/*
* Copyright (c) 2010 by Cristian Maglie <c.maglie@arduino.cc>
* Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
* Copyright (c) 2014 by Matthijs Kooijman <matthijs@stdin.nl> (SPISettings AVR)
* Copyright (c) 2014 by Andrew J. Kroll <xxxajk@gmail.com> (atomicity fixes)
* SPI Master library for arduino.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
#ifndef _SPI_H_INCLUDED
#define _SPI_H_INCLUDED
#include <Arduino.h>
// SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(),
// usingInterrupt(), and SPISetting(clock, bitOrder, dataMode)
#define SPI_HAS_TRANSACTION 1
// SPI_HAS_NOTUSINGINTERRUPT means that SPI has notUsingInterrupt() method
#define SPI_HAS_NOTUSINGINTERRUPT 1
// SPI_ATOMIC_VERSION means that SPI has atomicity fixes and what version.
// This way when there is a bug fix you can check this define to alert users
// of your code if it uses better version of this library.
// This also implies everything that SPI_HAS_TRANSACTION as documented above is
// available too.
#define SPI_ATOMIC_VERSION 1
// Uncomment this line to add detection of mismatched begin/end transactions.
// A mismatch occurs if other libraries fail to use SPI.endTransaction() for
// each SPI.beginTransaction(). Connect an LED to this pin. The LED will turn
// on if any mismatch is ever detected.
//#define SPI_TRANSACTION_MISMATCH_LED 5
#ifndef LSBFIRST
#define LSBFIRST 0
#endif
#ifndef MSBFIRST
#define MSBFIRST 1
#endif
#define SPI_CLOCK_DIV4 0x00
#define SPI_CLOCK_DIV16 0x01
#define SPI_CLOCK_DIV64 0x02
#define SPI_CLOCK_DIV128 0x03
#define SPI_CLOCK_DIV2 0x04
#define SPI_CLOCK_DIV8 0x05
#define SPI_CLOCK_DIV32 0x06
#define SPI_MODE0 0x00
#define SPI_MODE1 0x04
#define SPI_MODE2 0x08
#define SPI_MODE3 0x0C
#define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR
#define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR
#define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR
// define SPI_AVR_EIMSK for AVR boards with external interrupt pins
#if defined(EIMSK)
#define SPI_AVR_EIMSK EIMSK
#elif defined(GICR)
#define SPI_AVR_EIMSK GICR
#elif defined(GIMSK)
#define SPI_AVR_EIMSK GIMSK
#endif
class SPISettings {
public:
SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {
if (__builtin_constant_p(clock)) {
init_AlwaysInline(clock, bitOrder, dataMode);
} else {
init_MightInline(clock, bitOrder, dataMode);
}
}
SPISettings() {
init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0);
}
private:
void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {
init_AlwaysInline(clock, bitOrder, dataMode);
}
void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
__attribute__((__always_inline__)) {
// Clock settings are defined as follows. Note that this shows SPI2X
// inverted, so the bits form increasing numbers. Also note that
// fosc/64 appears twice
// SPR1 SPR0 ~SPI2X Freq
// 0 0 0 fosc/2
// 0 0 1 fosc/4
// 0 1 0 fosc/8
// 0 1 1 fosc/16
// 1 0 0 fosc/32
// 1 0 1 fosc/64
// 1 1 0 fosc/64
// 1 1 1 fosc/128
// We find the fastest clock that is less than or equal to the
// given clock rate. The clock divider that results in clock_setting
// is 2 ^^ (clock_div + 1). If nothing is slow enough, we'll use the
// slowest (128 == 2 ^^ 7, so clock_div = 6).
uint8_t clockDiv;
// When the clock is known at compiletime, use this if-then-else
// cascade, which the compiler knows how to completely optimize
// away. When clock is not known, use a loop instead, which generates
// shorter code.
if (__builtin_constant_p(clock)) {
if (clock >= F_CPU / 2) {
clockDiv = 0;
} else if (clock >= F_CPU / 4) {
clockDiv = 1;
} else if (clock >= F_CPU / 8) {
clockDiv = 2;
} else if (clock >= F_CPU / 16) {
clockDiv = 3;
} else if (clock >= F_CPU / 32) {
clockDiv = 4;
} else if (clock >= F_CPU / 64) {
clockDiv = 5;
} else {
clockDiv = 6;
}
} else {
uint32_t clockSetting = F_CPU / 2;
clockDiv = 0;
while (clockDiv < 6 && clock < clockSetting) {
clockSetting /= 2;
clockDiv++;
}
}
// Compensate for the duplicate fosc/64
if (clockDiv == 6)
clockDiv = 7;
// Invert the SPI2X bit
clockDiv ^= 0x1;
// Pack into the SPISettings class
spcr = _BV(SPE) | _BV(MSTR) | ((bitOrder == LSBFIRST) ? _BV(DORD) : 0) |
(dataMode & SPI_MODE_MASK) | ((clockDiv >> 1) & SPI_CLOCK_MASK);
spsr = clockDiv & SPI_2XCLOCK_MASK;
}
uint8_t spcr;
uint8_t spsr;
friend class SPIClass;
};
class SPIClass {
public:
// Initialize the SPI library
static void begin();
// If SPI is used from within an interrupt, this function registers
// that interrupt with the SPI library, so beginTransaction() can
// prevent conflicts. The input interruptNumber is the number used
// with attachInterrupt. If SPI is used from a different interrupt
// (eg, a timer), interruptNumber should be 255.
static void usingInterrupt(uint8_t interruptNumber);
// And this does the opposite.
static void notUsingInterrupt(uint8_t interruptNumber);
// Note: the usingInterrupt and notUsingInterrupt functions should
// not to be called from ISR context or inside a transaction.
// For details see:
// https://github.com/arduino/Arduino/pull/2381
// https://github.com/arduino/Arduino/pull/2449
// Before using SPI.transfer() or asserting chip select pins,
// this function is used to gain exclusive access to the SPI bus
// and configure the correct settings.
inline static void beginTransaction(SPISettings settings) {
if (interruptMode > 0) {
uint8_t sreg = SREG;
noInterrupts();
#ifdef SPI_AVR_EIMSK
if (interruptMode == 1) {
interruptSave = SPI_AVR_EIMSK;
SPI_AVR_EIMSK &= ~interruptMask;
SREG = sreg;
} else
#endif
{
interruptSave = sreg;
}
}
#ifdef SPI_TRANSACTION_MISMATCH_LED
if (inTransactionFlag) {
pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
}
inTransactionFlag = 1;
#endif
SPCR = settings.spcr;
SPSR = settings.spsr;
}
// Write to the SPI bus (MOSI pin) and also receive (MISO pin)
inline static uint8_t transfer(uint8_t data) {
SPDR = data;
/*
* The following NOP introduces a small delay that can prevent the wait
* loop form iterating when running at the maximum speed. This gives
* about 10% more speed, even if it seems counter-intuitive. At lower
* speeds it is unnoticed.
*/
asm volatile("nop");
while (!(SPSR & _BV(SPIF))) ; // wait
return SPDR;
}
inline static uint16_t transfer16(uint16_t data) {
union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } in, out;
in.val = data;
if (!(SPCR & _BV(DORD))) {
SPDR = in.msb;
asm volatile("nop"); // See transfer(uint8_t) function
while (!(SPSR & _BV(SPIF))) ;
out.msb = SPDR;
SPDR = in.lsb;
asm volatile("nop");
while (!(SPSR & _BV(SPIF))) ;
out.lsb = SPDR;
} else {
SPDR = in.lsb;
asm volatile("nop");
while (!(SPSR & _BV(SPIF))) ;
out.lsb = SPDR;
SPDR = in.msb;
asm volatile("nop");
while (!(SPSR & _BV(SPIF))) ;
out.msb = SPDR;
}
return out.val;
}
inline static void transfer(void *buf, size_t count) {
if (count == 0) return;
uint8_t *p = (uint8_t *)buf;
SPDR = *p;
while (--count > 0) {
uint8_t out = *(p + 1);
while (!(SPSR & _BV(SPIF))) ;
uint8_t in = SPDR;
SPDR = out;
*p++ = in;
}
while (!(SPSR & _BV(SPIF))) ;
*p = SPDR;
}
// After performing a group of transfers and releasing the chip select
// signal, this function allows others to access the SPI bus
inline static void endTransaction(void) {
#ifdef SPI_TRANSACTION_MISMATCH_LED
if (!inTransactionFlag) {
pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
}
inTransactionFlag = 0;
#endif
if (interruptMode > 0) {
#ifdef SPI_AVR_EIMSK
uint8_t sreg = SREG;
#endif
noInterrupts();
#ifdef SPI_AVR_EIMSK
if (interruptMode == 1) {
SPI_AVR_EIMSK = interruptSave;
SREG = sreg;
} else
#endif
{
SREG = interruptSave;
}
}
}
// Disable the SPI bus
static void end();
// This function is deprecated. New applications should use
// beginTransaction() to configure SPI settings.
inline static void setBitOrder(uint8_t bitOrder) {
if (bitOrder == LSBFIRST) SPCR |= _BV(DORD);
else SPCR &= ~(_BV(DORD));
}
// This function is deprecated. New applications should use
// beginTransaction() to configure SPI settings.
inline static void setDataMode(uint8_t dataMode) {
SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode;
}
// This function is deprecated. New applications should use
// beginTransaction() to configure SPI settings.
inline static void setClockDivider(uint8_t clockDiv) {
SPCR = (SPCR & ~SPI_CLOCK_MASK) | (clockDiv & SPI_CLOCK_MASK);
SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((clockDiv >> 2) & SPI_2XCLOCK_MASK);
}
// These undocumented functions should not be used. SPI.transfer()
// polls the hardware flag which is automatically cleared as the
// AVR responds to SPI's interrupt
inline static void attachInterrupt() { SPCR |= _BV(SPIE); }
inline static void detachInterrupt() { SPCR &= ~_BV(SPIE); }
private:
static uint8_t initialized;
static uint8_t interruptMode; // 0=none, 1=mask, 2=global
static uint8_t interruptMask; // which interrupts to mask
static uint8_t interruptSave; // temp storage, to restore state
#ifdef SPI_TRANSACTION_MISMATCH_LED
static uint8_t inTransactionFlag;
#endif
};
extern SPIClass SPI;
#endif

515
SimpleModbusMaster.cpp Normal file
View File

@ -0,0 +1,515 @@
#include "SimpleModbusMaster.h"
#include "HardwareSerial.h"
// state machine states
#define IDLE 1
#define WAITING_FOR_REPLY 2
#define WAITING_FOR_TURNAROUND 3
#define BUFFER_SIZE 128
unsigned char state;
unsigned char retry_count;
unsigned char TxEnablePin;
// frame[] is used to receive and transmit packages.
// The maximum number of bytes in a modbus packet is 256 bytes
// This is limited to the serial buffer of 128 bytes
unsigned char frame[BUFFER_SIZE];
unsigned char buffer;
unsigned int timeout; // timeout interval
unsigned int polling; // turnaround delay interval
unsigned int T1_5; // inter character time out in microseconds
unsigned long delayStart; // init variable for turnaround and timeout delay
unsigned int total_no_of_packets;
Packet* packetArray; // packet starting address
Packet* packet; // current packet
HardwareSerial* ModbusPort;
// function definitions
void idle();
void constructPacket();
unsigned char construct_F15();
unsigned char construct_F16();
void waiting_for_reply();
void processReply();
void waiting_for_turnaround();
void process_F1_F2();
void process_F3_F4();
void process_F15_F16();
void processError();
void processSuccess();
unsigned int calculateCRC(unsigned char bufferSize);
void sendPacket(unsigned char bufferSize);
// Modbus Master State Machine
void modbus_update()
{
switch (state)
{
case IDLE:
idle();
break;
case WAITING_FOR_REPLY:
waiting_for_reply();
break;
case WAITING_FOR_TURNAROUND:
waiting_for_turnaround();
break;
}
}
void idle()
{
static unsigned int packet_index;
unsigned int failed_connections = 0;
unsigned char current_connection;
do
{
if (packet_index == total_no_of_packets) // wrap around to the beginning
packet_index = 0;
// proceed to the next packet
packet = &packetArray[packet_index];
// get the current connection status
current_connection = packet->connection;
if (!current_connection)
{
// If all the connection attributes are false return
// immediately to the main sketch
if (++failed_connections == total_no_of_packets)
return;
}
packet_index++;
// if a packet has no connection get the next one
}while (!current_connection);
constructPacket();
}
void constructPacket()
{
packet->requests++;
frame[0] = packet->id;
frame[1] = packet->function;
frame[2] = packet->address >> 8; // address Hi
frame[3] = packet->address & 0xFF; // address Lo
// For functions 1 & 2 data is the number of points
// For functions 3, 4 & 16 data is the number of registers
// For function 15 data is the number of coils
frame[4] = packet->data >> 8; // MSB
frame[5] = packet->data & 0xFF; // LSB
unsigned char frameSize;
// construct the frame according to the modbus function
if (packet->function == PRESET_MULTIPLE_REGISTERS)
frameSize = construct_F16();
else if (packet->function == FORCE_MULTIPLE_COILS)
frameSize = construct_F15();
else // else functions 1,2,3 & 4 is assumed. They all share the exact same request format.
frameSize = 8; // the request is always 8 bytes in size for the above mentioned functions.
unsigned int crc16 = calculateCRC(frameSize - 2);
frame[frameSize - 2] = crc16 >> 8; // split crc into 2 bytes
frame[frameSize - 1] = crc16 & 0xFF;
sendPacket(frameSize);
state = WAITING_FOR_REPLY; // state change
// if broadcast is requested (id == 0) for function 15 or 16 then override
// the previous state and force a success since the slave wont respond
if (packet->id == 0)
processSuccess();
}
unsigned char construct_F15()
{
// function 15 coil information is packed LSB first until the first 16 bits are completed
// It is received the same way..
unsigned char no_of_registers = packet->data / 16;
unsigned char no_of_bytes = no_of_registers * 2;
// if the number of points dont fit in even 2byte amounts (one register) then use another register and pad
if (packet->data % 16 > 0)
{
no_of_registers++;
no_of_bytes++;
}
frame[6] = no_of_bytes;
unsigned char bytes_processed = 0;
unsigned char index = 7; // user data starts at index 7
unsigned int temp;
for (unsigned char i = 0; i < no_of_registers; i++)
{
temp = packet->register_array[i]; // get the data
frame[index] = temp & 0xFF;
bytes_processed++;
if (bytes_processed < no_of_bytes)
{
frame[index + 1] = temp >> 8;
bytes_processed++;
index += 2;
}
}
unsigned char frameSize = (9 + no_of_bytes); // first 7 bytes of the array + 2 bytes CRC + noOfBytes
return frameSize;
}
unsigned char construct_F16()
{
unsigned char no_of_bytes = packet->data * 2;
// first 6 bytes of the array + no_of_bytes + 2 bytes CRC
frame[6] = no_of_bytes; // number of bytes
unsigned char index = 7; // user data starts at index 7
unsigned char no_of_registers = packet->data;
unsigned int temp;
for (unsigned char i = 0; i < no_of_registers; i++)
{
temp = packet->register_array[i]; // get the data
frame[index] = temp >> 8;
index++;
frame[index] = temp & 0xFF;
index++;
}
unsigned char frameSize = (9 + no_of_bytes); // first 7 bytes of the array + 2 bytes CRC + noOfBytes
return frameSize;
}
void waiting_for_turnaround()
{
if ((millis() - delayStart) > polling)
state = IDLE;
}
// get the serial data from the buffer
void waiting_for_reply()
{
if ((*ModbusPort).available()) // is there something to check?
{
unsigned char overflowFlag = 0;
buffer = 0;
while ((*ModbusPort).available())
{
// The maximum number of bytes is limited to the serial buffer size
// of BUFFER_SIZE. If more bytes is received than the BUFFER_SIZE the
// overflow flag will be set and the serial buffer will be read until
// all the data is cleared from the receive buffer, while the slave is
// still responding.
if (overflowFlag)
(*ModbusPort).read();
else
{
if (buffer == BUFFER_SIZE)
overflowFlag = 1;
frame[buffer] = (*ModbusPort).read();
// Serial.print("R: "); Serial.println(frame[buffer], 16);
buffer++;
}
// This is not 100% correct but it will suffice.
// worst case scenario is if more than one character time expires
// while reading from the buffer then the buffer is most likely empty
// If there are more bytes after such a delay it is not supposed to
// be received and thus will force a frame_error.
delayMicroseconds(T1_5); // inter character time out
}
// The minimum buffer size from a slave can be an exception response of
// 5 bytes. If the buffer was partially filled set a frame_error.
// The maximum number of bytes in a modbus packet is 256 bytes.
// The serial buffer limits this to 128 bytes.
if ((buffer < 5) || overflowFlag)
processError();
// Modbus over serial line datasheet states that if an unexpected slave
// responded the master must do nothing and continue with the time out.
// This seems silly cause if an incorrect slave responded you would want to
// have a quick turnaround and poll the right one again. If an unexpected
// slave responded it will most likely be a frame error in any event
else if (frame[0] != packet->id) // check id returned
processError();
else
processReply();
}
else if ((millis() - delayStart) > timeout) // check timeout
{
processError();
state = IDLE; //state change, override processError() state
}
}
void processReply()
{
// combine the crc Low & High bytes
unsigned int received_crc = ((frame[buffer - 2] << 8) | frame[buffer - 1]);
unsigned int calculated_crc = calculateCRC(buffer - 2);
if (calculated_crc == received_crc) // verify checksum
{
// To indicate an exception response a slave will 'OR'
// the requested function with 0x80
if ((frame[1] & 0x80) == 0x80) // extract 0x80
{
packet->exception_errors++;
processError();
}
else
{
switch (frame[1]) // check function returned
{
case READ_COIL_STATUS:
case READ_INPUT_STATUS:
process_F1_F2();
break;
case READ_INPUT_REGISTERS:
case READ_HOLDING_REGISTERS:
process_F3_F4();
break;
case FORCE_MULTIPLE_COILS:
case PRESET_MULTIPLE_REGISTERS:
process_F15_F16();
break;
default: // illegal function returned
processError();
break;
}
}
}
else // checksum failed
{
processError();
}
}
void process_F1_F2()
{
// packet->data for function 1 & 2 is actually the number of boolean points
unsigned char no_of_registers = packet->data / 16;
unsigned char number_of_bytes = no_of_registers * 2;
// if the number of points dont fit in even 2byte amounts (one register) then use another register and pad
if (packet->data % 16 > 0)
{
no_of_registers++;
number_of_bytes++;
}
if (frame[2] == number_of_bytes) // check number of bytes returned
{
unsigned char bytes_processed = 0;
unsigned char index = 3; // start at the 4th element in the frame and combine the Lo byte
unsigned int temp;
for (unsigned char i = 0; i < no_of_registers; i++)
{
temp = frame[index];
bytes_processed++;
if (bytes_processed < number_of_bytes)
{
temp = (frame[index + 1] << 8) | temp;
bytes_processed++;
index += 2;
}
packet->register_array[i] = temp;
}
processSuccess();
}
else // incorrect number of bytes returned
processError();
}
void process_F3_F4()
{
// check number of bytes returned - unsigned int == 2 bytes
// data for function 3 & 4 is the number of registers
if (frame[2] == (packet->data * 2))
{
unsigned char index = 3;
for (unsigned char i = 0; i < packet->data; i++)
{
// start at the 4th element in the frame and combine the Lo byte
packet->register_array[i] = (frame[index] << 8) | frame[index + 1];
index += 2;
}
processSuccess();
}
else // incorrect number of bytes returned
processError();
}
void process_F15_F16()
{
// Functions 15 & 16 is just an echo of the query
unsigned int recieved_address = ((frame[2] << 8) | frame[3]);
unsigned int recieved_data = ((frame[4] << 8) | frame[5]);
if ((recieved_address == packet->address) && (recieved_data == packet->data))
processSuccess();
else
processError();
}
void processError()
{
packet->retries++;
packet->failed_requests++;
if (packet->valueValid != NULL) {
*(packet->valueValid) = false;
}
// if the number of retries have reached the max number of retries
// allowable, stop requesting the specific packet
if (packet->retries == retry_count)
{
packet->connection = 0;
packet->retries = 0;
if (packet->connectionValid != NULL) {
*(packet->connectionValid) = false;
}
}
state = WAITING_FOR_TURNAROUND;
delayStart = millis(); // start the turnaround delay
}
void processSuccess()
{
packet->successful_requests++; // transaction sent successfully
packet->retries = 0; // if a request was successful reset the retry counter
state = WAITING_FOR_TURNAROUND;
delayStart = millis(); // start the turnaround delay
if (packet->valueValid != NULL) {
*(packet->valueValid) = true;
}
if (packet->connectionValid != NULL) {
*(packet->connectionValid) = true;
}
}
void modbus_configure(HardwareSerial* SerialPort,
long baud,
unsigned char byteFormat,
unsigned int _timeout,
unsigned int _polling,
unsigned char _retry_count,
unsigned char _TxEnablePin,
Packet* _packets,
unsigned int _total_no_of_packets)
{
// Modbus states that a baud rate higher than 19200 must use a fixed 750 us
// for inter character time out and 1.75 ms for a frame delay for baud rates
// below 19200 the timing is more critical and has to be calculated.
// E.g. 9600 baud in a 11 bit packet is 9600/11 = 872 characters per second
// In milliseconds this will be 872 characters per 1000ms. So for 1 character
// 1000ms/872 characters is 1.14583ms per character and finally modbus states
// an inter-character must be 1.5T or 1.5 times longer than a character. Thus
// 1.5T = 1.14583ms * 1.5 = 1.71875ms. A frame delay is 3.5T.
// Thus the formula is T1.5(us) = (1000ms * 1000(us) * 1.5 * 11bits)/baud
// 1000ms * 1000(us) * 1.5 * 11bits = 16500000 can be calculated as a constant
if (baud > 19200)
T1_5 = 750;
else
T1_5 = 16500000/baud; // 1T * 1.5 = T1.5
// initialize
state = IDLE;
timeout = _timeout;
polling = _polling;
retry_count = _retry_count;
TxEnablePin = _TxEnablePin;
total_no_of_packets = _total_no_of_packets;
packetArray = _packets;
// initialize connection status of each packet
/*for (unsigned char i = 0; i < total_no_of_packets; i++)
{
_packets->connection = 1;
_packets++;
}*/
ModbusPort = SerialPort;
(*ModbusPort).begin(baud, byteFormat);
pinMode(TxEnablePin, OUTPUT);
digitalWrite(TxEnablePin, LOW);
}
void modbus_construct(Packet *_packet,
unsigned char id,
unsigned char function,
unsigned int address,
unsigned int data,
unsigned int* register_array)
{
_packet->id = id;
_packet->function = function;
_packet->address = address;
_packet->data = data;
_packet->register_array = register_array;
_packet->connection = 1;
_packet->connectionValid = NULL;
_packet->valueValid = NULL;
}
unsigned int calculateCRC(unsigned char bufferSize)
{
unsigned int temp, temp2, flag;
temp = 0xFFFF;
for (unsigned char i = 0; i < bufferSize; i++)
{
temp = temp ^ frame[i];
for (unsigned char j = 1; j <= 8; j++)
{
flag = temp & 0x0001;
temp >>= 1;
if (flag)
temp ^= 0xA001;
}
}
// Reverse byte order.
temp2 = temp >> 8;
temp = (temp << 8) | temp2;
temp &= 0xFFFF;
// the returned value is already swapped
// crcLo byte is first & crcHi byte is last
return temp;
}
void sendPacket(unsigned char bufferSize)
{
digitalWrite(TxEnablePin, HIGH);
for (unsigned char i = 0; i < bufferSize; i++) {
// Serial.print("S: "); Serial.println(frame[i],16);
(*ModbusPort).write(frame[i]);
}
(*ModbusPort).flush();
// It may be necessary to add a another character delay T1_5 here to
// avoid truncating the message on slow and long distance connections
digitalWrite(TxEnablePin, LOW);
delayStart = millis(); // start the timeout delay
}

139
SimpleModbusMaster.h Normal file
View File

@ -0,0 +1,139 @@
#ifndef SIMPLE_MODBUS_MASTER_H
#define SIMPLE_MODBUS_MASTER_H
// SimpleModbusMasterV10
/*
SimpleModbusMaster allows you to communicate
to any slave using the Modbus RTU protocol.
To communicate with a slave you need to create a packet that will contain
all the information required to communicate to the slave.
Information counters are implemented for further diagnostic.
These are variables already implemented in a packet.
You can set and clear these variables as needed.
The following modbus information counters are implemented:
requests - contains the total requests to a slave
successful_requests - contains the total successful requests
failed_requests - general frame errors, checksum failures and buffer failures
retries - contains the number of retries
exception_errors - contains the specific modbus exception response count
These are normally illegal function, illegal address, illegal data value
or a miscellaneous error response.
And finally there is a variable called "connection" that
at any given moment contains the current connection
status of the packet. If true then the connection is
active. If false then communication will be stopped
on this packet until the programmer sets the connection
variable to true explicitly. The reason for this is
because of the time out involved in modbus communication.
Each faulty slave that's not communicating will slow down
communication on the line with the time out value. E.g.
Using a time out of 1500ms, if you have 10 slaves and 9 of them
stops communicating the latency burden placed on communication
will be 1500ms * 9 = 13,5 seconds!
Communication will automatically be stopped after the retry count expires
on each specific packet.
All the error checking, updating and communication multitasking
takes place in the background.
In general to communicate with to a slave using modbus
RTU you will request information using the specific
slave id, the function request, the starting address
and lastly the data to request.
Function 1, 2, 3, 4, 15 & 16 are supported. In addition to
this broadcasting (id = 0) is supported for function 15 & 16.
Constants are provided for:
Function 1 - READ_COIL_STATUS
Function 2 - READ_INPUT_STATUS
Function 3 - READ_HOLDING_REGISTERS
Function 4 - READ_INPUT_REGISTERS
Function 15 - FORCE_MULTIPLE_COILS
Function 16 - PRESET_MULTIPLE_REGISTERS
Note:
The Arduino serial ring buffer is 128 bytes or 64 registers.
Most of the time you will connect the Arduino using a MAX485 or similar.
In a function 3 or 4 request the master will attempt to read from a
slave and since 5 bytes is already used for ID, FUNCTION, NO OF BYTES
and two BYTES CRC the master can only request 122 bytes or 61 registers.
In a function 16 request the master will attempt to write to a
slave and since 9 bytes is already used for ID, FUNCTION, ADDRESS,
NO OF REGISTERS, NO OF BYTES and two BYTES CRC the master can only write
118 bytes or 59 registers.
Note:
Using a USB to Serial converter the maximum bytes you can send is
limited to its internal buffer which differs between manufactures.
Since it is assumed that you will mostly use the Arduino to connect without
using a USB to Serial converter the internal buffer is set the same as the
Arduino Serial ring buffer which is 128 bytes.
*/
#include "Arduino.h"
#define READ_COIL_STATUS 1 // Reads the ON/OFF status of discrete outputs (0X references, coils) in the slave.
#define READ_INPUT_STATUS 2 // Reads the ON/OFF status of discrete inputs (1X references) in the slave.
#define READ_HOLDING_REGISTERS 3 // Reads the binary contents of holding registers (4X references) in the slave.
#define READ_INPUT_REGISTERS 4 // Reads the binary contents of input registers (3X references) in the slave. Not writable.
#define FORCE_MULTIPLE_COILS 15 // Forces each coil (0X reference) in a sequence of coils to either ON or OFF.
#define PRESET_MULTIPLE_REGISTERS 16 // Presets values into a sequence of holding registers (4X references).
typedef struct
{
// specific packet info
unsigned char id;
unsigned char function;
unsigned int address;
// For functions 1 & 2 data is the number of points
// For functions 3, 4 & 16 data is the number of registers
// For function 15 data is the number of coils
unsigned int data;
unsigned int* register_array;
// modbus information counters
unsigned int requests;
unsigned int successful_requests;
unsigned int failed_requests;
unsigned int exception_errors;
unsigned int retries;
// connection status of packet
unsigned char connection;
bool *connectionValid;
bool *valueValid;
}Packet;
typedef Packet* packetPointer;
// function definitions
void modbus_update();
void modbus_construct(Packet *_packet,
unsigned char id,
unsigned char function,
unsigned int address,
unsigned int data,
unsigned int* register_array);
void modbus_configure(HardwareSerial* SerialPort,
long baud,
unsigned char byteFormat,
unsigned int _timeout,
unsigned int _polling,
unsigned char _retry_count,
unsigned char _TxEnablePin,
Packet* _packets,
unsigned int _total_no_of_packets);
#endif

105
Streaming.h Normal file
View File

@ -0,0 +1,105 @@
/*
Streaming.h - Arduino library for supporting the << streaming operator
Copyright (c) 2010-2012 Mikal Hart. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ARDUINO_STREAMING
#define ARDUINO_STREAMING
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#define STREAMING_LIBRARY_VERSION 5
// Generic template
template<class T>
inline Print &operator <<(Print &stream, T arg)
{ stream.print(arg); return stream; }
struct _BASED
{
long val;
int base;
_BASED(long v, int b): val(v), base(b)
{}
};
#if ARDUINO >= 100
struct _BYTE_CODE
{
byte val;
_BYTE_CODE(byte v) : val(v)
{}
};
#define _BYTE(a) _BYTE_CODE(a)
inline Print &operator <<(Print &obj, const _BYTE_CODE &arg)
{ obj.write(arg.val); return obj; }
#else
#define _BYTE(a) _BASED(a, BYTE)
#endif
#define _HEX(a) _BASED(a, HEX)
#define _DEC(a) _BASED(a, DEC)
#define _OCT(a) _BASED(a, OCT)
#define _BIN(a) _BASED(a, BIN)
// Specialization for class _BASED
// Thanks to Arduino forum user Ben Combee who suggested this
// clever technique to allow for expressions like
// Serial << _HEX(a);
inline Print &operator <<(Print &obj, const _BASED &arg)
{ obj.print(arg.val, arg.base); return obj; }
#if ARDUINO >= 18
// Specialization for class _FLOAT
// Thanks to Michael Margolis for suggesting a way
// to accommodate Arduino 0018's floating point precision
// feature like this:
// Serial << _FLOAT(gps_latitude, 6); // 6 digits of precision
struct _FLOAT
{
float val;
int digits;
_FLOAT(double v, int d): val(v), digits(d)
{}
};
inline Print &operator <<(Print &obj, const _FLOAT &arg)
{ obj.print(arg.val, arg.digits); return obj; }
#endif
// Specialization for enum _EndLineCode
// Thanks to Arduino forum user Paul V. who suggested this
// clever technique to allow for expressions like
// Serial << "Hello!" << endl;
enum _EndLineCode { endl };
inline Print &operator <<(Print &obj, _EndLineCode arg)
{ obj.println(); return obj; }
#endif

250
WiFi/WiFi.cpp Normal file
View File

@ -0,0 +1,250 @@
/*
WiFi.cpp - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "utility/wifi_drv.h"
#include "WiFi.h"
extern "C" {
#include "utility/wl_definitions.h"
#include "utility/wl_types.h"
#include "utility/debug.h"
}
// XXX: don't make assumptions about the value of MAX_SOCK_NUM.
int16_t WiFiClass::_state[MAX_SOCK_NUM] = { NA_STATE, NA_STATE, NA_STATE, NA_STATE };
uint16_t WiFiClass::_server_port[MAX_SOCK_NUM] = { 0, 0, 0, 0 };
WiFiClass::WiFiClass()
{
// Driver initialization
init();
}
void WiFiClass::init()
{
WiFiDrv::wifiDriverInit();
}
uint8_t WiFiClass::getSocket()
{
for (uint8_t i = 0; i < MAX_SOCK_NUM; ++i)
{
if (WiFiClass::_server_port[i] == 0)
{
return i;
}
}
return NO_SOCKET_AVAIL;
}
char* WiFiClass::firmwareVersion()
{
return WiFiDrv::getFwVersion();
}
int WiFiClass::begin(char* ssid)
{
uint8_t status = WL_IDLE_STATUS;
uint8_t attempts = WL_MAX_ATTEMPT_CONNECTION;
if (WiFiDrv::wifiSetNetwork(ssid, strlen(ssid)) != WL_FAILURE)
{
do
{
delay(WL_DELAY_START_CONNECTION);
status = WiFiDrv::getConnectionStatus();
}
while ((( status == WL_IDLE_STATUS)||(status == WL_SCAN_COMPLETED))&&(--attempts>0));
}else
{
status = WL_CONNECT_FAILED;
}
return status;
}
int WiFiClass::begin(char* ssid, uint8_t key_idx, const char *key)
{
uint8_t status = WL_IDLE_STATUS;
uint8_t attempts = WL_MAX_ATTEMPT_CONNECTION;
// set encryption key
if (WiFiDrv::wifiSetKey(ssid, strlen(ssid), key_idx, key, strlen(key)) != WL_FAILURE)
{
do
{
delay(WL_DELAY_START_CONNECTION);
status = WiFiDrv::getConnectionStatus();
}while ((( status == WL_IDLE_STATUS)||(status == WL_SCAN_COMPLETED))&&(--attempts>0));
}else{
status = WL_CONNECT_FAILED;
}
return status;
}
int WiFiClass::begin(char* ssid, const char *passphrase)
{
uint8_t status = WL_IDLE_STATUS;
uint8_t attempts = WL_MAX_ATTEMPT_CONNECTION;
// set passphrase
if (WiFiDrv::wifiSetPassphrase(ssid, strlen(ssid), passphrase, strlen(passphrase))!= WL_FAILURE)
{
do
{
delay(WL_DELAY_START_CONNECTION);
status = WiFiDrv::getConnectionStatus();
}
while ((( status == WL_IDLE_STATUS)||(status == WL_SCAN_COMPLETED))&&(--attempts>0));
}else{
status = WL_CONNECT_FAILED;
}
return status;
}
void WiFiClass::config(IPAddress local_ip)
{
WiFiDrv::config(1, (uint32_t)local_ip, 0, 0);
}
void WiFiClass::config(IPAddress local_ip, IPAddress dns_server)
{
WiFiDrv::config(1, (uint32_t)local_ip, 0, 0);
WiFiDrv::setDNS(1, (uint32_t)dns_server, 0);
}
void WiFiClass::config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway)
{
WiFiDrv::config(2, (uint32_t)local_ip, (uint32_t)gateway, 0);
WiFiDrv::setDNS(1, (uint32_t)dns_server, 0);
}
void WiFiClass::config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet)
{
WiFiDrv::config(3, (uint32_t)local_ip, (uint32_t)gateway, (uint32_t)subnet);
WiFiDrv::setDNS(1, (uint32_t)dns_server, 0);
}
void WiFiClass::setDNS(IPAddress dns_server1)
{
WiFiDrv::setDNS(1, (uint32_t)dns_server1, 0);
}
void WiFiClass::setDNS(IPAddress dns_server1, IPAddress dns_server2)
{
WiFiDrv::setDNS(2, (uint32_t)dns_server1, (uint32_t)dns_server2);
}
int WiFiClass::disconnect()
{
return WiFiDrv::disconnect();
}
uint8_t* WiFiClass::macAddress(uint8_t* mac)
{
uint8_t* _mac = WiFiDrv::getMacAddress();
memcpy(mac, _mac, WL_MAC_ADDR_LENGTH);
return mac;
}
IPAddress WiFiClass::localIP()
{
IPAddress ret;
WiFiDrv::getIpAddress(ret);
return ret;
}
IPAddress WiFiClass::subnetMask()
{
IPAddress ret;
WiFiDrv::getSubnetMask(ret);
return ret;
}
IPAddress WiFiClass::gatewayIP()
{
IPAddress ret;
WiFiDrv::getGatewayIP(ret);
return ret;
}
char* WiFiClass::SSID()
{
return WiFiDrv::getCurrentSSID();
}
uint8_t* WiFiClass::BSSID(uint8_t* bssid)
{
uint8_t* _bssid = WiFiDrv::getCurrentBSSID();
memcpy(bssid, _bssid, WL_MAC_ADDR_LENGTH);
return bssid;
}
int32_t WiFiClass::RSSI()
{
return WiFiDrv::getCurrentRSSI();
}
uint8_t WiFiClass::encryptionType()
{
return WiFiDrv::getCurrentEncryptionType();
}
int8_t WiFiClass::scanNetworks()
{
uint8_t attempts = 10;
uint8_t numOfNetworks = 0;
if (WiFiDrv::startScanNetworks() == WL_FAILURE)
return WL_FAILURE;
do
{
delay(2000);
numOfNetworks = WiFiDrv::getScanNetworks();
}
while (( numOfNetworks == 0)&&(--attempts>0));
return numOfNetworks;
}
char* WiFiClass::SSID(uint8_t networkItem)
{
return WiFiDrv::getSSIDNetoworks(networkItem);
}
int32_t WiFiClass::RSSI(uint8_t networkItem)
{
return WiFiDrv::getRSSINetoworks(networkItem);
}
uint8_t WiFiClass::encryptionType(uint8_t networkItem)
{
return WiFiDrv::getEncTypeNetowrks(networkItem);
}
uint8_t WiFiClass::status()
{
return WiFiDrv::getConnectionStatus();
}
int WiFiClass::hostByName(const char* aHostname, IPAddress& aResult)
{
return WiFiDrv::getHostByName(aHostname, aResult);
}
WiFiClass WiFi;

246
WiFi/WiFi.h Normal file
View File

@ -0,0 +1,246 @@
/*
WiFi.h - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef WiFi_h
#define WiFi_h
#include <inttypes.h>
extern "C" {
#include "utility/wl_definitions.h"
#include "utility/wl_types.h"
}
#include "IPAddress.h"
#include "WiFiClient.h"
#include "WiFiServer.h"
class WiFiClass
{
private:
static void init();
public:
static int16_t _state[MAX_SOCK_NUM];
static uint16_t _server_port[MAX_SOCK_NUM];
WiFiClass();
/*
* Get the first socket available
*/
static uint8_t getSocket();
/*
* Get firmware version
*/
static char* firmwareVersion();
/* Start Wifi connection for OPEN networks
*
* param ssid: Pointer to the SSID string.
*/
int begin(char* ssid);
/* Start Wifi connection with WEP encryption.
* Configure a key into the device. The key type (WEP-40, WEP-104)
* is determined by the size of the key (5 bytes for WEP-40, 13 bytes for WEP-104).
*
* param ssid: Pointer to the SSID string.
* param key_idx: The key index to set. Valid values are 0-3.
* param key: Key input buffer.
*/
int begin(char* ssid, uint8_t key_idx, const char* key);
/* Start Wifi connection with passphrase
* the most secure supported mode will be automatically selected
*
* param ssid: Pointer to the SSID string.
* param passphrase: Passphrase. Valid characters in a passphrase
* must be between ASCII 32-126 (decimal).
*/
int begin(char* ssid, const char *passphrase);
/* Change Ip configuration settings disabling the dhcp client
*
* param local_ip: Static ip configuration
*/
void config(IPAddress local_ip);
/* Change Ip configuration settings disabling the dhcp client
*
* param local_ip: Static ip configuration
* param dns_server: IP configuration for DNS server 1
*/
void config(IPAddress local_ip, IPAddress dns_server);
/* Change Ip configuration settings disabling the dhcp client
*
* param local_ip: Static ip configuration
* param dns_server: IP configuration for DNS server 1
* param gateway : Static gateway configuration
*/
void config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway);
/* Change Ip configuration settings disabling the dhcp client
*
* param local_ip: Static ip configuration
* param dns_server: IP configuration for DNS server 1
* param gateway: Static gateway configuration
* param subnet: Static Subnet mask
*/
void config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet);
/* Change DNS Ip configuration
*
* param dns_server1: ip configuration for DNS server 1
*/
void setDNS(IPAddress dns_server1);
/* Change DNS Ip configuration
*
* param dns_server1: ip configuration for DNS server 1
* param dns_server2: ip configuration for DNS server 2
*
*/
void setDNS(IPAddress dns_server1, IPAddress dns_server2);
/*
* Disconnect from the network
*
* return: one value of wl_status_t enum
*/
int disconnect(void);
/*
* Get the interface MAC address.
*
* return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
*/
uint8_t* macAddress(uint8_t* mac);
/*
* Get the interface IP address.
*
* return: Ip address value
*/
IPAddress localIP();
/*
* Get the interface subnet mask address.
*
* return: subnet mask address value
*/
IPAddress subnetMask();
/*
* Get the gateway ip address.
*
* return: gateway ip address value
*/
IPAddress gatewayIP();
/*
* Return the current SSID associated with the network
*
* return: ssid string
*/
char* SSID();
/*
* Return the current BSSID associated with the network.
* It is the MAC address of the Access Point
*
* return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
*/
uint8_t* BSSID(uint8_t* bssid);
/*
* Return the current RSSI /Received Signal Strength in dBm)
* associated with the network
*
* return: signed value
*/
int32_t RSSI();
/*
* Return the Encryption Type associated with the network
*
* return: one value of wl_enc_type enum
*/
uint8_t encryptionType();
/*
* Start scan WiFi networks available
*
* return: Number of discovered networks
*/
int8_t scanNetworks();
/*
* Return the SSID discovered during the network scan.
*
* param networkItem: specify from which network item want to get the information
*
* return: ssid string of the specified item on the networks scanned list
*/
char* SSID(uint8_t networkItem);
/*
* Return the encryption type of the networks discovered during the scanNetworks
*
* param networkItem: specify from which network item want to get the information
*
* return: encryption type (enum wl_enc_type) of the specified item on the networks scanned list
*/
uint8_t encryptionType(uint8_t networkItem);
/*
* Return the RSSI of the networks discovered during the scanNetworks
*
* param networkItem: specify from which network item want to get the information
*
* return: signed value of RSSI of the specified item on the networks scanned list
*/
int32_t RSSI(uint8_t networkItem);
/*
* Return Connection status.
*
* return: one of the value defined in wl_status_t
*/
uint8_t status();
/*
* Resolve the given hostname to an IP address.
* param aHostname: Name to be resolved
* param aResult: IPAddress structure to store the returned IP address
* result: 1 if aIPAddrString was successfully converted to an IP address,
* else error code
*/
int hostByName(const char* aHostname, IPAddress& aResult);
friend class WiFiClient;
friend class WiFiServer;
};
extern WiFiClass WiFi;
#endif

200
WiFi/WiFiClient.cpp Normal file
View File

@ -0,0 +1,200 @@
/*
WiFiClient.cpp - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
extern "C" {
#include "utility/wl_definitions.h"
#include "utility/wl_types.h"
#include "string.h"
#include "utility/debug.h"
}
#include "WiFi.h"
#include "WiFiClient.h"
#include "WiFiServer.h"
#include "utility/server_drv.h"
uint16_t WiFiClient::_srcport = 1024;
WiFiClient::WiFiClient() : _sock(MAX_SOCK_NUM) {
}
WiFiClient::WiFiClient(uint8_t sock) : _sock(sock) {
}
int WiFiClient::connect(const char* host, uint16_t port) {
IPAddress remote_addr;
if (WiFi.hostByName(host, remote_addr))
{
return connect(remote_addr, port);
}
return 0;
}
int WiFiClient::connect(IPAddress ip, uint16_t port) {
_sock = getFirstSocket();
if (_sock != NO_SOCKET_AVAIL)
{
ServerDrv::startClient(uint32_t(ip), port, _sock);
WiFiClass::_state[_sock] = _sock;
unsigned long start = millis();
// wait 4 second for the connection to close
while (!connected() && millis() - start < 10000)
delay(1);
if (!connected())
{
return 0;
}
}else{
Serial.println("No Socket available");
return 0;
}
return 1;
}
size_t WiFiClient::write(uint8_t b) {
return write(&b, 1);
}
size_t WiFiClient::write(const uint8_t *buf, size_t size) {
if (_sock >= MAX_SOCK_NUM)
{
setWriteError();
return 0;
}
if (size==0)
{
setWriteError();
return 0;
}
if (!ServerDrv::sendData(_sock, buf, size))
{
setWriteError();
return 0;
}
if (!ServerDrv::checkDataSent(_sock))
{
setWriteError();
return 0;
}
return size;
}
int WiFiClient::available() {
if (_sock != 255)
{
return ServerDrv::availData(_sock);
}
return 0;
}
int WiFiClient::read() {
uint8_t b;
if (!available())
return -1;
ServerDrv::getData(_sock, &b);
return b;
}
int WiFiClient::read(uint8_t* buf, size_t size) {
// sizeof(size_t) is architecture dependent
// but we need a 16 bit data type here
uint16_t _size = size;
if (!ServerDrv::getDataBuf(_sock, buf, &_size))
return -1;
return 0;
}
int WiFiClient::peek() {
uint8_t b;
if (!available())
return -1;
ServerDrv::getData(_sock, &b, 1);
return b;
}
void WiFiClient::flush() {
while (available())
read();
}
void WiFiClient::stop() {
if (_sock == 255)
return;
ServerDrv::stopClient(_sock);
WiFiClass::_state[_sock] = NA_STATE;
int count = 0;
// wait maximum 5 secs for the connection to close
while (status() != CLOSED && ++count < 50)
delay(100);
_sock = 255;
}
uint8_t WiFiClient::connected() {
if (_sock == 255) {
return 0;
} else {
uint8_t s = status();
return !(s == LISTEN || s == CLOSED || s == FIN_WAIT_1 ||
s == FIN_WAIT_2 || s == TIME_WAIT ||
s == SYN_SENT || s== SYN_RCVD ||
(s == CLOSE_WAIT));
}
}
uint8_t WiFiClient::status() {
if (_sock == 255) {
return CLOSED;
} else {
return ServerDrv::getClientState(_sock);
}
}
WiFiClient::operator bool() {
return _sock != 255;
}
// Private Methods
uint8_t WiFiClient::getFirstSocket()
{
for (int i = 0; i < MAX_SOCK_NUM; i++) {
if (WiFiClass::_state[i] == NA_STATE)
{
return i;
}
}
return SOCK_NOT_AVAIL;
}

59
WiFi/WiFiClient.h Normal file
View File

@ -0,0 +1,59 @@
/*
WiFiClient.cpp - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef wificlient_h
#define wificlient_h
#include "Arduino.h"
#include "Print.h"
#include "Client.h"
#include "IPAddress.h"
class WiFiClient : public Client {
public:
WiFiClient();
WiFiClient(uint8_t sock);
uint8_t status();
virtual int connect(IPAddress ip, uint16_t port);
virtual int connect(const char *host, uint16_t port);
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *buf, size_t size);
virtual int available();
virtual int read();
virtual int read(uint8_t *buf, size_t size);
virtual int peek();
virtual void flush();
virtual void stop();
virtual uint8_t connected();
virtual operator bool();
friend class WiFiServer;
using Print::write;
private:
static uint16_t _srcport;
uint8_t _sock; //not used
uint16_t _socket;
uint8_t getFirstSocket();
};
#endif

108
WiFi/WiFiServer.cpp Normal file
View File

@ -0,0 +1,108 @@
/*
WiFiServer.cpp - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <string.h>
#include "utility/server_drv.h"
extern "C" {
#include "utility/debug.h"
}
#include "WiFi.h"
#include "WiFiClient.h"
#include "WiFiServer.h"
WiFiServer::WiFiServer(uint16_t port)
{
_port = port;
}
void WiFiServer::begin()
{
uint8_t _sock = WiFiClass::getSocket();
if (_sock != NO_SOCKET_AVAIL)
{
ServerDrv::startServer(_port, _sock);
WiFiClass::_server_port[_sock] = _port;
WiFiClass::_state[_sock] = _sock;
}
}
WiFiClient WiFiServer::available(byte* status)
{
static int cycle_server_down = 0;
const int TH_SERVER_DOWN = 50;
for (int sock = 0; sock < MAX_SOCK_NUM; sock++)
{
if (WiFiClass::_server_port[sock] == _port)
{
WiFiClient client(sock);
uint8_t _status = client.status();
uint8_t _ser_status = this->status();
if (status != NULL)
*status = _status;
//server not in listen state, restart it
if ((_ser_status == 0)&&(cycle_server_down++ > TH_SERVER_DOWN))
{
ServerDrv::startServer(_port, sock);
cycle_server_down = 0;
}
if (_status == ESTABLISHED)
{
return client; //TODO
}
}
}
return WiFiClient(255);
}
uint8_t WiFiServer::status() {
return ServerDrv::getServerState(0);
}
size_t WiFiServer::write(uint8_t b)
{
return write(&b, 1);
}
size_t WiFiServer::write(const uint8_t *buffer, size_t size)
{
size_t n = 0;
for (int sock = 0; sock < MAX_SOCK_NUM; sock++)
{
if (WiFiClass::_server_port[sock] != 0)
{
WiFiClient client(sock);
if (WiFiClass::_server_port[sock] == _port &&
client.status() == ESTABLISHED)
{
n+=client.write(buffer, size);
}
}
}
return n;
}

46
WiFi/WiFiServer.h Normal file
View File

@ -0,0 +1,46 @@
/*
WiFiServer.h - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef wifiserver_h
#define wifiserver_h
extern "C" {
#include "utility/wl_definitions.h"
}
#include "Server.h"
class WiFiClient;
class WiFiServer : public Server {
private:
uint16_t _port;
void* pcb;
public:
WiFiServer(uint16_t);
WiFiClient available(uint8_t* status = NULL);
void begin();
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *buf, size_t size);
uint8_t status();
using Print::write;
};
#endif

181
WiFi/WiFiUdp.cpp Normal file
View File

@ -0,0 +1,181 @@
/*
WiFiUdp.cpp - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
extern "C" {
#include "utility/debug.h"
#include "utility/wifi_spi.h"
}
#include <string.h>
#include "utility/server_drv.h"
#include "utility/wifi_drv.h"
#include "WiFi.h"
#include "WiFiUdp.h"
#include "WiFiClient.h"
#include "WiFiServer.h"
/* Constructor */
WiFiUDP::WiFiUDP() : _sock(NO_SOCKET_AVAIL) {}
/* Start WiFiUDP socket, listening at local port PORT */
uint8_t WiFiUDP::begin(uint16_t port) {
uint8_t sock = WiFiClass::getSocket();
if (sock != NO_SOCKET_AVAIL)
{
ServerDrv::startServer(port, sock, UDP_MODE);
WiFiClass::_server_port[sock] = port;
_sock = sock;
_port = port;
return 1;
}
return 0;
}
/* return number of bytes available in the current packet,
will return zero if parsePacket hasn't been called yet */
int WiFiUDP::available() {
if (_sock != NO_SOCKET_AVAIL)
{
return ServerDrv::availData(_sock);
}
return 0;
}
/* Release any resources being used by this WiFiUDP instance */
void WiFiUDP::stop()
{
if (_sock == NO_SOCKET_AVAIL)
return;
ServerDrv::stopClient(_sock);
_sock = NO_SOCKET_AVAIL;
}
int WiFiUDP::beginPacket(const char *host, uint16_t port)
{
// Look up the host first
int ret = 0;
IPAddress remote_addr;
if (WiFi.hostByName(host, remote_addr))
{
return beginPacket(remote_addr, port);
}
return ret;
}
int WiFiUDP::beginPacket(IPAddress ip, uint16_t port)
{
if (_sock == NO_SOCKET_AVAIL)
_sock = WiFiClass::getSocket();
if (_sock != NO_SOCKET_AVAIL)
{
ServerDrv::startClient(uint32_t(ip), port, _sock, UDP_MODE);
WiFiClass::_state[_sock] = _sock;
return 1;
}
return 0;
}
int WiFiUDP::endPacket()
{
return ServerDrv::sendUdpData(_sock);
}
size_t WiFiUDP::write(uint8_t byte)
{
return write(&byte, 1);
}
size_t WiFiUDP::write(const uint8_t *buffer, size_t size)
{
ServerDrv::insertDataBuf(_sock, buffer, size);
return size;
}
int WiFiUDP::parsePacket()
{
return available();
}
int WiFiUDP::read()
{
uint8_t b;
if (available())
{
ServerDrv::getData(_sock, &b);
return b;
}else{
return -1;
}
}
int WiFiUDP::read(unsigned char* buffer, size_t len)
{
if (available())
{
uint16_t size = 0;
if (!ServerDrv::getDataBuf(_sock, buffer, &size))
return -1;
// TODO check if the buffer is too smal respect to buffer size
return size;
}else{
return -1;
}
}
int WiFiUDP::peek()
{
uint8_t b;
if (!available())
return -1;
ServerDrv::getData(_sock, &b, 1);
return b;
}
void WiFiUDP::flush()
{
while (available())
read();
}
IPAddress WiFiUDP::remoteIP()
{
uint8_t _remoteIp[4] = {0};
uint8_t _remotePort[2] = {0};
WiFiDrv::getRemoteData(_sock, _remoteIp, _remotePort);
IPAddress ip(_remoteIp);
return ip;
}
uint16_t WiFiUDP::remotePort()
{
uint8_t _remoteIp[4] = {0};
uint8_t _remotePort[2] = {0};
WiFiDrv::getRemoteData(_sock, _remoteIp, _remotePort);
uint16_t port = (_remotePort[0]<<8)+_remotePort[1];
return port;
}

80
WiFi/WiFiUdp.h Normal file
View File

@ -0,0 +1,80 @@
/*
WiFiUdp.h - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef wifiudp_h
#define wifiudp_h
#include <Udp.h>
#define UDP_TX_PACKET_MAX_SIZE 24
class WiFiUDP : public UDP {
private:
uint8_t _sock; // socket ID for Wiz5100
uint16_t _port; // local port to listen on
public:
WiFiUDP(); // Constructor
virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
virtual void stop(); // Finish with the UDP socket
// Sending UDP packets
// Start building up a packet to send to the remote host specific in ip and port
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
virtual int beginPacket(IPAddress ip, uint16_t port);
// Start building up a packet to send to the remote host specific in host and port
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
virtual int beginPacket(const char *host, uint16_t port);
// Finish off this packet and send it
// Returns 1 if the packet was sent successfully, 0 if there was an error
virtual int endPacket();
// Write a single byte into the packet
virtual size_t write(uint8_t);
// Write size bytes from buffer into the packet
virtual size_t write(const uint8_t *buffer, size_t size);
using Print::write;
// Start processing the next available incoming packet
// Returns the size of the packet in bytes, or 0 if no packets are available
virtual int parsePacket();
// Number of bytes remaining in the current packet
virtual int available();
// Read a single byte from the current packet
virtual int read();
// Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available
virtual int read(unsigned char* buffer, size_t len);
// Read up to len characters from the current packet and place them into buffer
// Returns the number of characters read, or 0 if none are available
virtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); };
// Return the next byte from the current packet without moving on to the next byte
virtual int peek();
virtual void flush(); // Finish reading the current packet
// Return the IP address of the host who sent the current incoming packet
virtual IPAddress remoteIP();
// Return the port of the host who sent the current incoming packet
virtual uint16_t remotePort();
friend class WiFiDrv;
};
#endif

95
WiFi/utility/debug.h Normal file
View File

@ -0,0 +1,95 @@
/*
debug.h - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
//*********************************************/
//
// File: debug.h
//
// Author: dlf (Metodo2 srl)
//
//********************************************/
#ifndef Debug_H
#define Debug_H
#include <stdio.h>
#include <string.h>
#define PRINT_FILE_LINE() do { \
Serial.print("[");Serial.print(__FILE__); \
Serial.print("::");Serial.print(__LINE__);Serial.print("]");\
}while (0);
#ifdef _DEBUG_
#define INFO(format, args...) do { \
char buf[250]; \
sprintf(buf, format, args); \
Serial.println(buf); \
} while(0);
#define INFO1(x) do { PRINT_FILE_LINE() Serial.print("-I-");\
Serial.println(x); \
}while (0);
#define INFO2(x,y) do { PRINT_FILE_LINE() Serial.print("-I-");\
Serial.print(x,16);Serial.print(",");Serial.println(y,16); \
}while (0);
#else
#define INFO1(x) do {} while(0);
#define INFO2(x,y) do {} while(0);
#define INFO(format, args...) do {} while(0);
#endif
#if 0
#define WARN(args) do { PRINT_FILE_LINE() \
Serial.print("-W-"); Serial.println(args); \
}while (0);
#else
#define WARN(args) do {} while (0);
#endif
#if _DEBUG_SPI_
#define DBG_PIN2 5
#define DBG_PIN 4
#define START() digitalWrite(DBG_PIN2, HIGH);
#define END() digitalWrite(DBG_PIN2, LOW);
#define SET_TRIGGER() digitalWrite(DBG_PIN, HIGH);
#define RST_TRIGGER() digitalWrite(DBG_PIN, LOW);
#define INIT_TRIGGER() pinMode(DBG_PIN, OUTPUT); \
pinMode(DBG_PIN2, OUTPUT); \
RST_TRIGGER()
#define TOGGLE_TRIGGER() SET_TRIGGER() \
delayMicroseconds(2); \
RST_TRIGGER()
#else
#define START()
#define END()
#define SET_TRIGGER()
#define RST_TRIGGER()
#define INIT_TRIGGER()
#define TOGGLE_TRIGGER()
#endif
#endif

327
WiFi/utility/server_drv.cpp Normal file
View File

@ -0,0 +1,327 @@
/*
server_drv.cpp - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
//#define _DEBUG_
#include "utility/server_drv.h"
#include "Arduino.h"
#include "utility/spi_drv.h"
extern "C" {
#include "utility/wl_types.h"
#include "utility/debug.h"
}
// Start server TCP on port specified
void ServerDrv::startServer(uint16_t port, uint8_t sock, uint8_t protMode)
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(START_SERVER_TCP_CMD, PARAM_NUMS_3);
SpiDrv::sendParam(port);
SpiDrv::sendParam(&sock, 1);
SpiDrv::sendParam(&protMode, 1, LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _data = 0;
uint8_t _dataLen = 0;
if (!SpiDrv::waitResponseCmd(START_SERVER_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen))
{
WARN("error waitResponse");
}
SpiDrv::spiSlaveDeselect();
}
// Start server TCP on port specified
void ServerDrv::startClient(uint32_t ipAddress, uint16_t port, uint8_t sock, uint8_t protMode)
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(START_CLIENT_TCP_CMD, PARAM_NUMS_4);
SpiDrv::sendParam((uint8_t*)&ipAddress, sizeof(ipAddress));
SpiDrv::sendParam(port);
SpiDrv::sendParam(&sock, 1);
SpiDrv::sendParam(&protMode, 1, LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _data = 0;
uint8_t _dataLen = 0;
if (!SpiDrv::waitResponseCmd(START_CLIENT_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen))
{
WARN("error waitResponse");
}
SpiDrv::spiSlaveDeselect();
}
// Start server TCP on port specified
void ServerDrv::stopClient(uint8_t sock)
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(STOP_CLIENT_TCP_CMD, PARAM_NUMS_1);
SpiDrv::sendParam(&sock, 1, LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _data = 0;
uint8_t _dataLen = 0;
if (!SpiDrv::waitResponseCmd(STOP_CLIENT_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen))
{
WARN("error waitResponse");
}
SpiDrv::spiSlaveDeselect();
}
uint8_t ServerDrv::getServerState(uint8_t sock)
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(GET_STATE_TCP_CMD, PARAM_NUMS_1);
SpiDrv::sendParam(&sock, sizeof(sock), LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _data = 0;
uint8_t _dataLen = 0;
if (!SpiDrv::waitResponseCmd(GET_STATE_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen))
{
WARN("error waitResponse");
}
SpiDrv::spiSlaveDeselect();
return _data;
}
uint8_t ServerDrv::getClientState(uint8_t sock)
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(GET_CLIENT_STATE_TCP_CMD, PARAM_NUMS_1);
SpiDrv::sendParam(&sock, sizeof(sock), LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _data = 0;
uint8_t _dataLen = 0;
if (!SpiDrv::waitResponseCmd(GET_CLIENT_STATE_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen))
{
WARN("error waitResponse");
}
SpiDrv::spiSlaveDeselect();
return _data;
}
uint16_t ServerDrv::availData(uint8_t sock)
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(AVAIL_DATA_TCP_CMD, PARAM_NUMS_1);
SpiDrv::sendParam(&sock, sizeof(sock), LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _dataLen = 0;
uint16_t len = 0;
SpiDrv::waitResponseCmd(AVAIL_DATA_TCP_CMD, PARAM_NUMS_1, (uint8_t*)&len, &_dataLen);
SpiDrv::spiSlaveDeselect();
return len;
}
bool ServerDrv::getData(uint8_t sock, uint8_t *data, uint8_t peek)
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(GET_DATA_TCP_CMD, PARAM_NUMS_2);
SpiDrv::sendParam(&sock, sizeof(sock));
SpiDrv::sendParam(peek, LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _data = 0;
uint8_t _dataLen = 0;
if (!SpiDrv::waitResponseData8(GET_DATA_TCP_CMD, &_data, &_dataLen))
{
WARN("error waitResponse");
}
SpiDrv::spiSlaveDeselect();
if (_dataLen!=0)
{
*data = _data;
return true;
}
return false;
}
bool ServerDrv::getDataBuf(uint8_t sock, uint8_t *_data, uint16_t *_dataLen)
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(GET_DATABUF_TCP_CMD, PARAM_NUMS_1);
SpiDrv::sendBuffer(&sock, sizeof(sock), LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
if (!SpiDrv::waitResponseData16(GET_DATABUF_TCP_CMD, _data, _dataLen))
{
WARN("error waitResponse");
}
SpiDrv::spiSlaveDeselect();
if (*_dataLen!=0)
{
return true;
}
return false;
}
bool ServerDrv::insertDataBuf(uint8_t sock, const uint8_t *data, uint16_t _len)
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(INSERT_DATABUF_CMD, PARAM_NUMS_2);
SpiDrv::sendBuffer(&sock, sizeof(sock));
SpiDrv::sendBuffer((uint8_t *)data, _len, LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _data = 0;
uint8_t _dataLen = 0;
if (!SpiDrv::waitResponseData8(INSERT_DATABUF_CMD, &_data, &_dataLen))
{
WARN("error waitResponse");
}
SpiDrv::spiSlaveDeselect();
if (_dataLen!=0)
{
return (_data == 1);
}
return false;
}
bool ServerDrv::sendUdpData(uint8_t sock)
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(SEND_DATA_UDP_CMD, PARAM_NUMS_1);
SpiDrv::sendParam(&sock, sizeof(sock), LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _data = 0;
uint8_t _dataLen = 0;
if (!SpiDrv::waitResponseData8(SEND_DATA_UDP_CMD, &_data, &_dataLen))
{
WARN("error waitResponse");
}
SpiDrv::spiSlaveDeselect();
if (_dataLen!=0)
{
return (_data == 1);
}
return false;
}
bool ServerDrv::sendData(uint8_t sock, const uint8_t *data, uint16_t len)
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(SEND_DATA_TCP_CMD, PARAM_NUMS_2);
SpiDrv::sendBuffer(&sock, sizeof(sock));
SpiDrv::sendBuffer((uint8_t *)data, len, LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _data = 0;
uint8_t _dataLen = 0;
if (!SpiDrv::waitResponseData8(SEND_DATA_TCP_CMD, &_data, &_dataLen))
{
WARN("error waitResponse");
}
SpiDrv::spiSlaveDeselect();
if (_dataLen!=0)
{
return (_data == 1);
}
return false;
}
uint8_t ServerDrv::checkDataSent(uint8_t sock)
{
const uint16_t TIMEOUT_DATA_SENT = 25;
uint16_t timeout = 0;
uint8_t _data = 0;
uint8_t _dataLen = 0;
do {
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(DATA_SENT_TCP_CMD, PARAM_NUMS_1);
SpiDrv::sendParam(&sock, sizeof(sock), LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
if (!SpiDrv::waitResponseCmd(DATA_SENT_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen))
{
WARN("error waitResponse isDataSent");
}
SpiDrv::spiSlaveDeselect();
if (_data) timeout = 0;
else{
++timeout;
delay(100);
}
}while((_data==0)&&(timeout<TIMEOUT_DATA_SENT));
return (timeout==TIMEOUT_DATA_SENT)?0:1;
}
ServerDrv serverDrv;

60
WiFi/utility/server_drv.h Normal file
View File

@ -0,0 +1,60 @@
/*
server_drv.h - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef Server_Drv_h
#define Server_Drv_h
#include <inttypes.h>
#include "utility/wifi_spi.h"
typedef enum eProtMode {TCP_MODE, UDP_MODE}tProtMode;
class ServerDrv
{
public:
// Start server TCP on port specified
static void startServer(uint16_t port, uint8_t sock, uint8_t protMode=TCP_MODE);
static void startClient(uint32_t ipAddress, uint16_t port, uint8_t sock, uint8_t protMode=TCP_MODE);
static void stopClient(uint8_t sock);
static uint8_t getServerState(uint8_t sock);
static uint8_t getClientState(uint8_t sock);
static bool getData(uint8_t sock, uint8_t *data, uint8_t peek = 0);
static bool getDataBuf(uint8_t sock, uint8_t *data, uint16_t *len);
static bool insertDataBuf(uint8_t sock, const uint8_t *_data, uint16_t _dataLen);
static bool sendData(uint8_t sock, const uint8_t *data, uint16_t len);
static bool sendUdpData(uint8_t sock);
static uint16_t availData(uint8_t sock);
static uint8_t checkDataSent(uint8_t sock);
};
extern ServerDrv serverDrv;
#endif

496
WiFi/utility/spi_drv.cpp Normal file
View File

@ -0,0 +1,496 @@
/*
spi_drv.cpp - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "Arduino.h"
#include <SPI.h>
#include "utility/spi_drv.h"
#include "pins_arduino.h"
//#define _DEBUG_
extern "C" {
#include "utility/debug.h"
}
#define DATAOUT 11 // MOSI
#define DATAIN 12 // MISO
#define SPICLOCK 13 // sck
#define SLAVESELECT 10 // ss
#define SLAVEREADY 7 // handshake pin
#define WIFILED 9 // led on wifi shield
#define DELAY_SPI(X) { int ii=0; do { asm volatile("nop"); } while (++ii < (X*F_CPU/16000000)); }
#define DELAY_TRANSFER() DELAY_SPI(10)
void SpiDrv::begin()
{
SPI.begin();
pinMode(SLAVESELECT, OUTPUT);
pinMode(SLAVEREADY, INPUT);
pinMode(WIFILED, OUTPUT);
digitalWrite(SCK, LOW);
digitalWrite(MOSI, LOW);
digitalWrite(SS, HIGH);
digitalWrite(SLAVESELECT, HIGH);
digitalWrite(WIFILED, LOW);
#ifdef _DEBUG_
INIT_TRIGGER()
#endif
}
void SpiDrv::end() {
SPI.end();
}
void SpiDrv::spiSlaveSelect()
{
digitalWrite(SLAVESELECT,LOW);
}
void SpiDrv::spiSlaveDeselect()
{
digitalWrite(SLAVESELECT,HIGH);
}
char SpiDrv::spiTransfer(volatile char data)
{
char result = SPI.transfer(data);
DELAY_TRANSFER();
return result; // return the received byte
}
int SpiDrv::waitSpiChar(unsigned char waitChar)
{
int timeout = TIMEOUT_CHAR;
unsigned char _readChar = 0;
do{
_readChar = readChar(); //get data byte
if (_readChar == ERR_CMD)
{
WARN("Err cmd received\n");
return -1;
}
}while((timeout-- > 0) && (_readChar != waitChar));
return (_readChar == waitChar);
}
int SpiDrv::readAndCheckChar(char checkChar, char* readChar)
{
getParam((uint8_t*)readChar);
return (*readChar == checkChar);
}
char SpiDrv::readChar()
{
uint8_t readChar = 0;
getParam(&readChar);
return readChar;
}
#define WAIT_START_CMD(x) waitSpiChar(START_CMD)
#define IF_CHECK_START_CMD(x) \
if (!WAIT_START_CMD(_data)) \
{ \
TOGGLE_TRIGGER() \
WARN("Error waiting START_CMD"); \
return 0; \
}else \
#define CHECK_DATA(check, x) \
if (!readAndCheckChar(check, &x)) \
{ \
TOGGLE_TRIGGER() \
WARN("Reply error"); \
INFO2(check, (uint8_t)x); \
return 0; \
}else \
#define waitSlaveReady() (digitalRead(SLAVEREADY) == LOW)
#define waitSlaveSign() (digitalRead(SLAVEREADY) == HIGH)
#define waitSlaveSignalH() while(digitalRead(SLAVEREADY) != HIGH){}
#define waitSlaveSignalL() while(digitalRead(SLAVEREADY) != LOW){}
void SpiDrv::waitForSlaveSign()
{
while (!waitSlaveSign());
}
void SpiDrv::waitForSlaveReady()
{
while (!waitSlaveReady());
}
void SpiDrv::getParam(uint8_t* param)
{
// Get Params data
*param = spiTransfer(DUMMY_DATA);
DELAY_TRANSFER();
}
int SpiDrv::waitResponseCmd(uint8_t cmd, uint8_t numParam, uint8_t* param, uint8_t* param_len)
{
char _data = 0;
int ii = 0;
IF_CHECK_START_CMD(_data)
{
CHECK_DATA(cmd | REPLY_FLAG, _data){};
CHECK_DATA(numParam, _data);
{
readParamLen8(param_len);
for (ii=0; ii<(*param_len); ++ii)
{
// Get Params data
//param[ii] = spiTransfer(DUMMY_DATA);
getParam(&param[ii]);
}
}
readAndCheckChar(END_CMD, &_data);
}
return 1;
}
/*
int SpiDrv::waitResponse(uint8_t cmd, uint8_t numParam, uint8_t* param, uint16_t* param_len)
{
char _data = 0;
int i =0, ii = 0;
IF_CHECK_START_CMD(_data)
{
CHECK_DATA(cmd | REPLY_FLAG, _data){};
CHECK_DATA(numParam, _data);
{
readParamLen16(param_len);
for (ii=0; ii<(*param_len); ++ii)
{
// Get Params data
param[ii] = spiTransfer(DUMMY_DATA);
}
}
readAndCheckChar(END_CMD, &_data);
}
return 1;
}
*/
int SpiDrv::waitResponseData16(uint8_t cmd, uint8_t* param, uint16_t* param_len)
{
char _data = 0;
uint16_t ii = 0;
IF_CHECK_START_CMD(_data)
{
CHECK_DATA(cmd | REPLY_FLAG, _data){};
uint8_t numParam = readChar();
if (numParam != 0)
{
readParamLen16(param_len);
for (ii=0; ii<(*param_len); ++ii)
{
// Get Params data
param[ii] = spiTransfer(DUMMY_DATA);
}
}
readAndCheckChar(END_CMD, &_data);
}
return 1;
}
int SpiDrv::waitResponseData8(uint8_t cmd, uint8_t* param, uint8_t* param_len)
{
char _data = 0;
int ii = 0;
IF_CHECK_START_CMD(_data)
{
CHECK_DATA(cmd | REPLY_FLAG, _data){};
uint8_t numParam = readChar();
if (numParam != 0)
{
readParamLen8(param_len);
for (ii=0; ii<(*param_len); ++ii)
{
// Get Params data
param[ii] = spiTransfer(DUMMY_DATA);
}
}
readAndCheckChar(END_CMD, &_data);
}
return 1;
}
int SpiDrv::waitResponseParams(uint8_t cmd, uint8_t numParam, tParam* params)
{
char _data = 0;
int i =0, ii = 0;
IF_CHECK_START_CMD(_data)
{
CHECK_DATA(cmd | REPLY_FLAG, _data){};
uint8_t _numParam = readChar();
if (_numParam != 0)
{
for (i=0; i<_numParam; ++i)
{
params[i].paramLen = readParamLen8();
for (ii=0; ii<params[i].paramLen; ++ii)
{
// Get Params data
params[i].param[ii] = spiTransfer(DUMMY_DATA);
}
}
} else
{
WARN("Error numParam == 0");
return 0;
}
if (numParam != _numParam)
{
WARN("Mismatch numParam");
return 0;
}
readAndCheckChar(END_CMD, &_data);
}
return 1;
}
/*
int SpiDrv::waitResponse(uint8_t cmd, tParam* params, uint8_t* numParamRead, uint8_t maxNumParams)
{
char _data = 0;
int i =0, ii = 0;
IF_CHECK_START_CMD(_data)
{
CHECK_DATA(cmd | REPLY_FLAG, _data){};
uint8_t numParam = readChar();
if (numParam > maxNumParams)
{
numParam = maxNumParams;
}
*numParamRead = numParam;
if (numParam != 0)
{
for (i=0; i<numParam; ++i)
{
params[i].paramLen = readParamLen8();
for (ii=0; ii<params[i].paramLen; ++ii)
{
// Get Params data
params[i].param[ii] = spiTransfer(DUMMY_DATA);
}
}
} else
{
WARN("Error numParams == 0");
Serial.println(cmd, 16);
return 0;
}
readAndCheckChar(END_CMD, &_data);
}
return 1;
}
*/
int SpiDrv::waitResponse(uint8_t cmd, uint8_t* numParamRead, uint8_t** params, uint8_t maxNumParams)
{
char _data = 0;
int i =0, ii = 0;
char *index[WL_SSID_MAX_LENGTH];
for (i = 0 ; i < WL_NETWORKS_LIST_MAXNUM ; i++)
index[i] = (char *)params + WL_SSID_MAX_LENGTH*i;
IF_CHECK_START_CMD(_data)
{
CHECK_DATA(cmd | REPLY_FLAG, _data){};
uint8_t numParam = readChar();
if (numParam > maxNumParams)
{
numParam = maxNumParams;
}
*numParamRead = numParam;
if (numParam != 0)
{
for (i=0; i<numParam; ++i)
{
uint8_t paramLen = readParamLen8();
for (ii=0; ii<paramLen; ++ii)
{
//ssid[ii] = spiTransfer(DUMMY_DATA);
// Get Params data
index[i][ii] = (uint8_t)spiTransfer(DUMMY_DATA);
}
index[i][ii]=0;
}
} else
{
WARN("Error numParams == 0");
readAndCheckChar(END_CMD, &_data);
return 0;
}
readAndCheckChar(END_CMD, &_data);
}
return 1;
}
void SpiDrv::sendParam(uint8_t* param, uint8_t param_len, uint8_t lastParam)
{
int i = 0;
// Send Spi paramLen
sendParamLen8(param_len);
// Send Spi param data
for (i=0; i<param_len; ++i)
{
spiTransfer(param[i]);
}
// if lastParam==1 Send Spi END CMD
if (lastParam == 1)
spiTransfer(END_CMD);
}
void SpiDrv::sendParamLen8(uint8_t param_len)
{
// Send Spi paramLen
spiTransfer(param_len);
}
void SpiDrv::sendParamLen16(uint16_t param_len)
{
// Send Spi paramLen
spiTransfer((uint8_t)((param_len & 0xff00)>>8));
spiTransfer((uint8_t)(param_len & 0xff));
}
uint8_t SpiDrv::readParamLen8(uint8_t* param_len)
{
uint8_t _param_len = spiTransfer(DUMMY_DATA);
if (param_len != NULL)
{
*param_len = _param_len;
}
return _param_len;
}
uint16_t SpiDrv::readParamLen16(uint16_t* param_len)
{
uint16_t _param_len = spiTransfer(DUMMY_DATA)<<8 | (spiTransfer(DUMMY_DATA)& 0xff);
if (param_len != NULL)
{
*param_len = _param_len;
}
return _param_len;
}
void SpiDrv::sendBuffer(uint8_t* param, uint16_t param_len, uint8_t lastParam)
{
uint16_t i = 0;
// Send Spi paramLen
sendParamLen16(param_len);
// Send Spi param data
for (i=0; i<param_len; ++i)
{
spiTransfer(param[i]);
}
// if lastParam==1 Send Spi END CMD
if (lastParam == 1)
spiTransfer(END_CMD);
}
void SpiDrv::sendParam(uint16_t param, uint8_t lastParam)
{
// Send Spi paramLen
sendParamLen8(2);
spiTransfer((uint8_t)((param & 0xff00)>>8));
spiTransfer((uint8_t)(param & 0xff));
// if lastParam==1 Send Spi END CMD
if (lastParam == 1)
spiTransfer(END_CMD);
}
/* Cmd Struct Message */
/* _________________________________________________________________________________ */
/*| START CMD | C/R | CMD |[TOT LEN]| N.PARAM | PARAM LEN | PARAM | .. | END CMD | */
/*|___________|______|______|_________|_________|___________|________|____|_________| */
/*| 8 bit | 1bit | 7bit | 8bit | 8bit | 8bit | nbytes | .. | 8bit | */
/*|___________|______|______|_________|_________|___________|________|____|_________| */
void SpiDrv::sendCmd(uint8_t cmd, uint8_t numParam)
{
// Send Spi START CMD
spiTransfer(START_CMD);
//waitForSlaveSign();
//wait the interrupt trigger on slave
delayMicroseconds(SPI_START_CMD_DELAY);
// Send Spi C + cmd
spiTransfer(cmd & ~(REPLY_FLAG));
// Send Spi totLen
//spiTransfer(totLen);
// Send Spi numParam
spiTransfer(numParam);
// If numParam == 0 send END CMD
if (numParam == 0)
spiTransfer(END_CMD);
}
SpiDrv spiDrv;

102
WiFi/utility/spi_drv.h Normal file
View File

@ -0,0 +1,102 @@
/*
spi_drv.h - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef SPI_Drv_h
#define SPI_Drv_h
#include <inttypes.h>
#include "utility/wifi_spi.h"
#define SPI_START_CMD_DELAY 10
#define NO_LAST_PARAM 0
#define LAST_PARAM 1
#define DUMMY_DATA 0xFF
#define WAIT_FOR_SLAVE_SELECT() \
SpiDrv::waitForSlaveReady(); \
SpiDrv::spiSlaveSelect();
class SpiDrv
{
private:
//static bool waitSlaveReady();
static void waitForSlaveSign();
static void getParam(uint8_t* param);
public:
static void begin();
static void end();
static void spiDriverInit();
static void spiSlaveSelect();
static void spiSlaveDeselect();
static char spiTransfer(volatile char data);
static void waitForSlaveReady();
//static int waitSpiChar(char waitChar, char* readChar);
static int waitSpiChar(unsigned char waitChar);
static int readAndCheckChar(char checkChar, char* readChar);
static char readChar();
static int waitResponseParams(uint8_t cmd, uint8_t numParam, tParam* params);
static int waitResponseCmd(uint8_t cmd, uint8_t numParam, uint8_t* param, uint8_t* param_len);
static int waitResponseData8(uint8_t cmd, uint8_t* param, uint8_t* param_len);
static int waitResponseData16(uint8_t cmd, uint8_t* param, uint16_t* param_len);
/*
static int waitResponse(uint8_t cmd, tParam* params, uint8_t* numParamRead, uint8_t maxNumParams);
static int waitResponse(uint8_t cmd, uint8_t numParam, uint8_t* param, uint16_t* param_len);
*/
static int waitResponse(uint8_t cmd, uint8_t* numParamRead, uint8_t** params, uint8_t maxNumParams);
static void sendParam(uint8_t* param, uint8_t param_len, uint8_t lastParam = NO_LAST_PARAM);
static void sendParamLen8(uint8_t param_len);
static void sendParamLen16(uint16_t param_len);
static uint8_t readParamLen8(uint8_t* param_len = NULL);
static uint16_t readParamLen16(uint16_t* param_len = NULL);
static void sendBuffer(uint8_t* param, uint16_t param_len, uint8_t lastParam = NO_LAST_PARAM);
static void sendParam(uint16_t param, uint8_t lastParam = NO_LAST_PARAM);
static void sendCmd(uint8_t cmd, uint8_t numParam);
};
extern SpiDrv spiDrv;
#endif

579
WiFi/utility/wifi_drv.cpp Normal file
View File

@ -0,0 +1,579 @@
/*
wifi_drv.cpp - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "Arduino.h"
#include "utility/spi_drv.h"
#include "utility/wifi_drv.h"
#define _DEBUG_
extern "C" {
#include "utility/wifi_spi.h"
#include "utility/wl_types.h"
#include "utility/debug.h"
}
// Array of data to cache the information related to the networks discovered
char WiFiDrv::_networkSsid[][WL_SSID_MAX_LENGTH] = {{"1"},{"2"},{"3"},{"4"},{"5"}};
int32_t WiFiDrv::_networkRssi[WL_NETWORKS_LIST_MAXNUM] = { 0 };
uint8_t WiFiDrv::_networkEncr[WL_NETWORKS_LIST_MAXNUM] = { 0 };
// Cached values of retrieved data
char WiFiDrv::_ssid[] = {0};
uint8_t WiFiDrv::_bssid[] = {0};
uint8_t WiFiDrv::_mac[] = {0};
uint8_t WiFiDrv::_localIp[] = {0};
uint8_t WiFiDrv::_subnetMask[] = {0};
uint8_t WiFiDrv::_gatewayIp[] = {0};
// Firmware version
char WiFiDrv::fwVersion[] = {0};
// Private Methods
void WiFiDrv::getNetworkData(uint8_t *ip, uint8_t *mask, uint8_t *gwip)
{
tParam params[PARAM_NUMS_3] = { {0, (char*)ip}, {0, (char*)mask}, {0, (char*)gwip}};
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(GET_IPADDR_CMD, PARAM_NUMS_1);
uint8_t _dummy = DUMMY_DATA;
SpiDrv::sendParam(&_dummy, sizeof(_dummy), LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
SpiDrv::waitResponseParams(GET_IPADDR_CMD, PARAM_NUMS_3, params);
SpiDrv::spiSlaveDeselect();
}
void WiFiDrv::getRemoteData(uint8_t sock, uint8_t *ip, uint8_t *port)
{
tParam params[PARAM_NUMS_2] = { {0, (char*)ip}, {0, (char*)port} };
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(GET_REMOTE_DATA_CMD, PARAM_NUMS_1);
SpiDrv::sendParam(&sock, sizeof(sock), LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
SpiDrv::waitResponseParams(GET_REMOTE_DATA_CMD, PARAM_NUMS_2, params);
SpiDrv::spiSlaveDeselect();
}
// Public Methods
void WiFiDrv::wifiDriverInit()
{
SpiDrv::begin();
}
int8_t WiFiDrv::wifiSetNetwork(char* ssid, uint8_t ssid_len)
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(SET_NET_CMD, PARAM_NUMS_1);
SpiDrv::sendParam((uint8_t*)ssid, ssid_len, LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _data = 0;
uint8_t _dataLen = 0;
if (!SpiDrv::waitResponseCmd(SET_NET_CMD, PARAM_NUMS_1, &_data, &_dataLen))
{
WARN("error waitResponse");
_data = WL_FAILURE;
}
SpiDrv::spiSlaveDeselect();
return(_data == WIFI_SPI_ACK) ? WL_SUCCESS : WL_FAILURE;
}
int8_t WiFiDrv::wifiSetPassphrase(char* ssid, uint8_t ssid_len, const char *passphrase, const uint8_t len)
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(SET_PASSPHRASE_CMD, PARAM_NUMS_2);
SpiDrv::sendParam((uint8_t*)ssid, ssid_len, NO_LAST_PARAM);
SpiDrv::sendParam((uint8_t*)passphrase, len, LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _data = 0;
uint8_t _dataLen = 0;
if (!SpiDrv::waitResponseCmd(SET_PASSPHRASE_CMD, PARAM_NUMS_1, &_data, &_dataLen))
{
WARN("error waitResponse");
_data = WL_FAILURE;
}
SpiDrv::spiSlaveDeselect();
return _data;
}
int8_t WiFiDrv::wifiSetKey(char* ssid, uint8_t ssid_len, uint8_t key_idx, const void *key, const uint8_t len)
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(SET_KEY_CMD, PARAM_NUMS_3);
SpiDrv::sendParam((uint8_t*)ssid, ssid_len, NO_LAST_PARAM);
SpiDrv::sendParam(&key_idx, KEY_IDX_LEN, NO_LAST_PARAM);
SpiDrv::sendParam((uint8_t*)key, len, LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _data = 0;
uint8_t _dataLen = 0;
if (!SpiDrv::waitResponseCmd(SET_KEY_CMD, PARAM_NUMS_1, &_data, &_dataLen))
{
WARN("error waitResponse");
_data = WL_FAILURE;
}
SpiDrv::spiSlaveDeselect();
return _data;
}
void WiFiDrv::config(uint8_t validParams, uint32_t local_ip, uint32_t gateway, uint32_t subnet)
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(SET_IP_CONFIG_CMD, PARAM_NUMS_4);
SpiDrv::sendParam((uint8_t*)&validParams, 1, NO_LAST_PARAM);
SpiDrv::sendParam((uint8_t*)&local_ip, 4, NO_LAST_PARAM);
SpiDrv::sendParam((uint8_t*)&gateway, 4, NO_LAST_PARAM);
SpiDrv::sendParam((uint8_t*)&subnet, 4, LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _data = 0;
uint8_t _dataLen = 0;
if (!SpiDrv::waitResponseCmd(SET_IP_CONFIG_CMD, PARAM_NUMS_1, &_data, &_dataLen))
{
WARN("error waitResponse");
_data = WL_FAILURE;
}
SpiDrv::spiSlaveDeselect();
}
void WiFiDrv::setDNS(uint8_t validParams, uint32_t dns_server1, uint32_t dns_server2)
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(SET_DNS_CONFIG_CMD, PARAM_NUMS_3);
SpiDrv::sendParam((uint8_t*)&validParams, 1, NO_LAST_PARAM);
SpiDrv::sendParam((uint8_t*)&dns_server1, 4, NO_LAST_PARAM);
SpiDrv::sendParam((uint8_t*)&dns_server2, 4, LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _data = 0;
uint8_t _dataLen = 0;
if (!SpiDrv::waitResponseCmd(SET_DNS_CONFIG_CMD, PARAM_NUMS_1, &_data, &_dataLen))
{
WARN("error waitResponse");
_data = WL_FAILURE;
}
SpiDrv::spiSlaveDeselect();
}
int8_t WiFiDrv::disconnect()
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(DISCONNECT_CMD, PARAM_NUMS_1);
uint8_t _dummy = DUMMY_DATA;
SpiDrv::sendParam(&_dummy, 1, LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _data = 0;
uint8_t _dataLen = 0;
int8_t result = SpiDrv::waitResponseCmd(DISCONNECT_CMD, PARAM_NUMS_1, &_data, &_dataLen);
SpiDrv::spiSlaveDeselect();
return result;
}
uint8_t WiFiDrv::getConnectionStatus()
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(GET_CONN_STATUS_CMD, PARAM_NUMS_0);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _data = -1;
uint8_t _dataLen = 0;
SpiDrv::waitResponseCmd(GET_CONN_STATUS_CMD, PARAM_NUMS_1, &_data, &_dataLen);
SpiDrv::spiSlaveDeselect();
return _data;
}
uint8_t* WiFiDrv::getMacAddress()
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(GET_MACADDR_CMD, PARAM_NUMS_1);
uint8_t _dummy = DUMMY_DATA;
SpiDrv::sendParam(&_dummy, 1, LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _dataLen = 0;
SpiDrv::waitResponseCmd(GET_MACADDR_CMD, PARAM_NUMS_1, _mac, &_dataLen);
SpiDrv::spiSlaveDeselect();
return _mac;
}
void WiFiDrv::getIpAddress(IPAddress& ip)
{
getNetworkData(_localIp, _subnetMask, _gatewayIp);
ip = _localIp;
}
void WiFiDrv::getSubnetMask(IPAddress& mask)
{
getNetworkData(_localIp, _subnetMask, _gatewayIp);
mask = _subnetMask;
}
void WiFiDrv::getGatewayIP(IPAddress& ip)
{
getNetworkData(_localIp, _subnetMask, _gatewayIp);
ip = _gatewayIp;
}
char* WiFiDrv::getCurrentSSID()
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(GET_CURR_SSID_CMD, PARAM_NUMS_1);
uint8_t _dummy = DUMMY_DATA;
SpiDrv::sendParam(&_dummy, 1, LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _dataLen = 0;
SpiDrv::waitResponseCmd(GET_CURR_SSID_CMD, PARAM_NUMS_1, (uint8_t*)_ssid, &_dataLen);
SpiDrv::spiSlaveDeselect();
return _ssid;
}
uint8_t* WiFiDrv::getCurrentBSSID()
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(GET_CURR_BSSID_CMD, PARAM_NUMS_1);
uint8_t _dummy = DUMMY_DATA;
SpiDrv::sendParam(&_dummy, 1, LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _dataLen = 0;
SpiDrv::waitResponseCmd(GET_CURR_BSSID_CMD, PARAM_NUMS_1, _bssid, &_dataLen);
SpiDrv::spiSlaveDeselect();
return _bssid;
}
int32_t WiFiDrv::getCurrentRSSI()
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(GET_CURR_RSSI_CMD, PARAM_NUMS_1);
uint8_t _dummy = DUMMY_DATA;
SpiDrv::sendParam(&_dummy, 1, LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _dataLen = 0;
int32_t rssi = 0;
SpiDrv::waitResponseCmd(GET_CURR_RSSI_CMD, PARAM_NUMS_1, (uint8_t*)&rssi, &_dataLen);
SpiDrv::spiSlaveDeselect();
return rssi;
}
uint8_t WiFiDrv::getCurrentEncryptionType()
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(GET_CURR_ENCT_CMD, PARAM_NUMS_1);
uint8_t _dummy = DUMMY_DATA;
SpiDrv::sendParam(&_dummy, 1, LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t dataLen = 0;
uint8_t encType = 0;
SpiDrv::waitResponseCmd(GET_CURR_ENCT_CMD, PARAM_NUMS_1, (uint8_t*)&encType, &dataLen);
SpiDrv::spiSlaveDeselect();
return encType;
}
int8_t WiFiDrv::startScanNetworks()
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(START_SCAN_NETWORKS, PARAM_NUMS_0);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _data = 0;
uint8_t _dataLen = 0;
if (!SpiDrv::waitResponseCmd(START_SCAN_NETWORKS, PARAM_NUMS_1, &_data, &_dataLen))
{
WARN("error waitResponse");
_data = WL_FAILURE;
}
SpiDrv::spiSlaveDeselect();
return (_data == WL_FAILURE)? _data : WL_SUCCESS;
}
uint8_t WiFiDrv::getScanNetworks()
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(SCAN_NETWORKS, PARAM_NUMS_0);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t ssidListNum = 0;
SpiDrv::waitResponse(SCAN_NETWORKS, &ssidListNum, (uint8_t**)_networkSsid, WL_NETWORKS_LIST_MAXNUM);
SpiDrv::spiSlaveDeselect();
return ssidListNum;
}
char* WiFiDrv::getSSIDNetoworks(uint8_t networkItem)
{
if (networkItem >= WL_NETWORKS_LIST_MAXNUM)
return NULL;
return _networkSsid[networkItem];
}
uint8_t WiFiDrv::getEncTypeNetowrks(uint8_t networkItem)
{
if (networkItem >= WL_NETWORKS_LIST_MAXNUM)
return NULL;
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(GET_IDX_ENCT_CMD, PARAM_NUMS_1);
SpiDrv::sendParam(&networkItem, 1, LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t dataLen = 0;
uint8_t encType = 0;
SpiDrv::waitResponseCmd(GET_IDX_ENCT_CMD, PARAM_NUMS_1, (uint8_t*)&encType, &dataLen);
SpiDrv::spiSlaveDeselect();
return encType;
}
int32_t WiFiDrv::getRSSINetoworks(uint8_t networkItem)
{
if (networkItem >= WL_NETWORKS_LIST_MAXNUM)
return NULL;
int32_t networkRssi = 0;
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(GET_IDX_RSSI_CMD, PARAM_NUMS_1);
SpiDrv::sendParam(&networkItem, 1, LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t dataLen = 0;
SpiDrv::waitResponseCmd(GET_IDX_RSSI_CMD, PARAM_NUMS_1, (uint8_t*)&networkRssi, &dataLen);
SpiDrv::spiSlaveDeselect();
return networkRssi;
}
uint8_t WiFiDrv::reqHostByName(const char* aHostname)
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(REQ_HOST_BY_NAME_CMD, PARAM_NUMS_1);
SpiDrv::sendParam((uint8_t*)aHostname, strlen(aHostname), LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _data = 0;
uint8_t _dataLen = 0;
uint8_t result = SpiDrv::waitResponseCmd(REQ_HOST_BY_NAME_CMD, PARAM_NUMS_1, &_data, &_dataLen);
SpiDrv::spiSlaveDeselect();
return result;
}
int WiFiDrv::getHostByName(IPAddress& aResult)
{
uint8_t _ipAddr[WL_IPV4_LENGTH];
IPAddress dummy(0xFF,0xFF,0xFF,0xFF);
int result = 0;
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(GET_HOST_BY_NAME_CMD, PARAM_NUMS_0);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _dataLen = 0;
if (!SpiDrv::waitResponseCmd(GET_HOST_BY_NAME_CMD, PARAM_NUMS_1, _ipAddr, &_dataLen))
{
WARN("error waitResponse");
}else{
aResult = _ipAddr;
result = (aResult != dummy);
}
SpiDrv::spiSlaveDeselect();
return result;
}
int WiFiDrv::getHostByName(const char* aHostname, IPAddress& aResult)
{
uint8_t retry = 10;
if (reqHostByName(aHostname))
{
while(!getHostByName(aResult) && --retry > 0)
{
delay(1000);
}
}else{
return 0;
}
return (retry>0);
}
char* WiFiDrv::getFwVersion()
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(GET_FW_VERSION_CMD, PARAM_NUMS_0);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
uint8_t _dataLen = 0;
if (!SpiDrv::waitResponseCmd(GET_FW_VERSION_CMD, PARAM_NUMS_1, (uint8_t*)fwVersion, &_dataLen))
{
WARN("error waitResponse");
}
SpiDrv::spiSlaveDeselect();
return fwVersion;
}
WiFiDrv wiFiDrv;

267
WiFi/utility/wifi_drv.h Normal file
View File

@ -0,0 +1,267 @@
/*
wifi_drv.h - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef WiFi_Drv_h
#define WiFi_Drv_h
#include <inttypes.h>
#include "utility/wifi_spi.h"
#include "IPAddress.h"
#include "WiFiUdp.h"
// Key index length
#define KEY_IDX_LEN 1
// 5 secs of delay to have the connection established
#define WL_DELAY_START_CONNECTION 5000
// firmware version string length
#define WL_FW_VER_LENGTH 6
class WiFiDrv
{
private:
// settings of requested network
static char _networkSsid[WL_NETWORKS_LIST_MAXNUM][WL_SSID_MAX_LENGTH];
static int32_t _networkRssi[WL_NETWORKS_LIST_MAXNUM];
static uint8_t _networkEncr[WL_NETWORKS_LIST_MAXNUM];
// firmware version string in the format a.b.c
static char fwVersion[WL_FW_VER_LENGTH];
// settings of current selected network
static char _ssid[WL_SSID_MAX_LENGTH];
static uint8_t _bssid[WL_MAC_ADDR_LENGTH];
static uint8_t _mac[WL_MAC_ADDR_LENGTH];
static uint8_t _localIp[WL_IPV4_LENGTH];
static uint8_t _subnetMask[WL_IPV4_LENGTH];
static uint8_t _gatewayIp[WL_IPV4_LENGTH];
/*
* Get network Data information
*/
static void getNetworkData(uint8_t *ip, uint8_t *mask, uint8_t *gwip);
static uint8_t reqHostByName(const char* aHostname);
static int getHostByName(IPAddress& aResult);
/*
* Get remote Data information on UDP socket
*/
static void getRemoteData(uint8_t sock, uint8_t *ip, uint8_t *port);
public:
/*
* Driver initialization
*/
static void wifiDriverInit();
/*
* Set the desired network which the connection manager should try to
* connect to.
*
* The ssid of the desired network should be specified.
*
* param ssid: The ssid of the desired network.
* param ssid_len: Lenght of ssid string.
* return: WL_SUCCESS or WL_FAILURE
*/
static int8_t wifiSetNetwork(char* ssid, uint8_t ssid_len);
/* Start Wifi connection with passphrase
* the most secure supported mode will be automatically selected
*
* param ssid: Pointer to the SSID string.
* param ssid_len: Lenght of ssid string.
* param passphrase: Passphrase. Valid characters in a passphrase
* must be between ASCII 32-126 (decimal).
* param len: Lenght of passphrase string.
* return: WL_SUCCESS or WL_FAILURE
*/
static int8_t wifiSetPassphrase(char* ssid, uint8_t ssid_len, const char *passphrase, const uint8_t len);
/* Start Wifi connection with WEP encryption.
* Configure a key into the device. The key type (WEP-40, WEP-104)
* is determined by the size of the key (5 bytes for WEP-40, 13 bytes for WEP-104).
*
* param ssid: Pointer to the SSID string.
* param ssid_len: Lenght of ssid string.
* param key_idx: The key index to set. Valid values are 0-3.
* param key: Key input buffer.
* param len: Lenght of key string.
* return: WL_SUCCESS or WL_FAILURE
*/
static int8_t wifiSetKey(char* ssid, uint8_t ssid_len, uint8_t key_idx, const void *key, const uint8_t len);
/* Set ip configuration disabling dhcp client
*
* param validParams: set the number of parameters that we want to change
* i.e. validParams = 1 means that we'll change only ip address
* validParams = 3 means that we'll change ip address, gateway and netmask
* param local_ip: Static ip configuration
* param gateway: Static gateway configuration
* param subnet: Static subnet mask configuration
*/
static void config(uint8_t validParams, uint32_t local_ip, uint32_t gateway, uint32_t subnet);
/* Set DNS ip configuration
*
* param validParams: set the number of parameters that we want to change
* i.e. validParams = 1 means that we'll change only dns_server1
* validParams = 2 means that we'll change dns_server1 and dns_server2
* param dns_server1: Static DNS server1 configuration
* param dns_server2: Static DNS server2 configuration
*/
static void setDNS(uint8_t validParams, uint32_t dns_server1, uint32_t dns_server2);
/*
* Disconnect from the network
*
* return: WL_SUCCESS or WL_FAILURE
*/
static int8_t disconnect();
/*
* Disconnect from the network
*
* return: one value of wl_status_t enum
*/
static uint8_t getConnectionStatus();
/*
* Get the interface MAC address.
*
* return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
*/
static uint8_t* getMacAddress();
/*
* Get the interface IP address.
*
* return: copy the ip address value in IPAddress object
*/
static void getIpAddress(IPAddress& ip);
/*
* Get the interface subnet mask address.
*
* return: copy the subnet mask address value in IPAddress object
*/
static void getSubnetMask(IPAddress& mask);
/*
* Get the gateway ip address.
*
* return: copy the gateway ip address value in IPAddress object
*/
static void getGatewayIP(IPAddress& ip);
/*
* Return the current SSID associated with the network
*
* return: ssid string
*/
static char* getCurrentSSID();
/*
* Return the current BSSID associated with the network.
* It is the MAC address of the Access Point
*
* return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
*/
static uint8_t* getCurrentBSSID();
/*
* Return the current RSSI /Received Signal Strength in dBm)
* associated with the network
*
* return: signed value
*/
static int32_t getCurrentRSSI();
/*
* Return the Encryption Type associated with the network
*
* return: one value of wl_enc_type enum
*/
static uint8_t getCurrentEncryptionType();
/*
* Start scan WiFi networks available
*
* return: Number of discovered networks
*/
static int8_t startScanNetworks();
/*
* Get the networks available
*
* return: Number of discovered networks
*/
static uint8_t getScanNetworks();
/*
* Return the SSID discovered during the network scan.
*
* param networkItem: specify from which network item want to get the information
*
* return: ssid string of the specified item on the networks scanned list
*/
static char* getSSIDNetoworks(uint8_t networkItem);
/*
* Return the RSSI of the networks discovered during the scanNetworks
*
* param networkItem: specify from which network item want to get the information
*
* return: signed value of RSSI of the specified item on the networks scanned list
*/
static int32_t getRSSINetoworks(uint8_t networkItem);
/*
* Return the encryption type of the networks discovered during the scanNetworks
*
* param networkItem: specify from which network item want to get the information
*
* return: encryption type (enum wl_enc_type) of the specified item on the networks scanned list
*/
static uint8_t getEncTypeNetowrks(uint8_t networkItem);
/*
* Resolve the given hostname to an IP address.
* param aHostname: Name to be resolved
* param aResult: IPAddress structure to store the returned IP address
* result: 1 if aIPAddrString was successfully converted to an IP address,
* else error code
*/
static int getHostByName(const char* aHostname, IPAddress& aResult);
/*
* Get the firmware version
* result: version as string with this format a.b.c
*/
static char* getFwVersion();
friend class WiFiUDP;
};
extern WiFiDrv wiFiDrv;
#endif

173
WiFi/utility/wifi_spi.h Normal file
View File

@ -0,0 +1,173 @@
/*
wifi_spi.h - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef WiFi_Spi_h
#define WiFi_Spi_h
#include <inttypes.h>
#include "utility/wl_definitions.h"
#define CMD_FLAG 0
#define REPLY_FLAG 1<<7
#define DATA_FLAG 0x40
#define WIFI_SPI_ACK 1
#define WIFI_SPI_ERR 0xFF
#define TIMEOUT_CHAR 1000
//#define MAX_SOCK_NUM 4 /**< Maxmium number of socket */
#define NO_SOCKET_AVAIL 255
#define START_CMD 0xE0
#define END_CMD 0xEE
#define ERR_CMD 0xEF
#define CMD_POS 1 // Position of Command OpCode on SPI stream
#define PARAM_LEN_POS 2 // Position of Param len on SPI stream
enum {
SET_NET_CMD = 0x10,
SET_PASSPHRASE_CMD = 0x11,
SET_KEY_CMD = 0x12,
TEST_CMD = 0x13,
SET_IP_CONFIG_CMD = 0x14,
SET_DNS_CONFIG_CMD = 0x15,
GET_CONN_STATUS_CMD = 0x20,
GET_IPADDR_CMD = 0x21,
GET_MACADDR_CMD = 0x22,
GET_CURR_SSID_CMD = 0x23,
GET_CURR_BSSID_CMD = 0x24,
GET_CURR_RSSI_CMD = 0x25,
GET_CURR_ENCT_CMD = 0x26,
SCAN_NETWORKS = 0x27,
START_SERVER_TCP_CMD= 0x28,
GET_STATE_TCP_CMD = 0x29,
DATA_SENT_TCP_CMD = 0x2A,
AVAIL_DATA_TCP_CMD = 0x2B,
GET_DATA_TCP_CMD = 0x2C,
START_CLIENT_TCP_CMD= 0x2D,
STOP_CLIENT_TCP_CMD = 0x2E,
GET_CLIENT_STATE_TCP_CMD= 0x2F,
DISCONNECT_CMD = 0x30,
GET_IDX_SSID_CMD = 0x31,
GET_IDX_RSSI_CMD = 0x32,
GET_IDX_ENCT_CMD = 0x33,
REQ_HOST_BY_NAME_CMD= 0x34,
GET_HOST_BY_NAME_CMD= 0x35,
START_SCAN_NETWORKS = 0x36,
GET_FW_VERSION_CMD = 0x37,
GET_TEST_CMD = 0x38,
SEND_DATA_UDP_CMD = 0x39,
GET_REMOTE_DATA_CMD = 0x3A,
// All command with DATA_FLAG 0x40 send a 16bit Len
SEND_DATA_TCP_CMD = 0x44,
GET_DATABUF_TCP_CMD = 0x45,
INSERT_DATABUF_CMD = 0x46,
};
enum wl_tcp_state {
CLOSED = 0,
LISTEN = 1,
SYN_SENT = 2,
SYN_RCVD = 3,
ESTABLISHED = 4,
FIN_WAIT_1 = 5,
FIN_WAIT_2 = 6,
CLOSE_WAIT = 7,
CLOSING = 8,
LAST_ACK = 9,
TIME_WAIT = 10
};
enum numParams{
PARAM_NUMS_0,
PARAM_NUMS_1,
PARAM_NUMS_2,
PARAM_NUMS_3,
PARAM_NUMS_4,
PARAM_NUMS_5,
MAX_PARAM_NUMS
};
#define MAX_PARAMS MAX_PARAM_NUMS-1
#define PARAM_LEN_SIZE 1
typedef struct __attribute__((__packed__))
{
uint8_t paramLen;
char* param;
}tParam;
typedef struct __attribute__((__packed__))
{
uint16_t dataLen;
char* data;
}tDataParam;
typedef struct __attribute__((__packed__))
{
unsigned char cmd;
unsigned char tcmd;
unsigned char nParam;
tParam params[MAX_PARAMS];
}tSpiMsg;
typedef struct __attribute__((__packed__))
{
unsigned char cmd;
unsigned char tcmd;
unsigned char nParam;
tDataParam params[MAX_PARAMS];
}tSpiMsgData;
typedef struct __attribute__((__packed__))
{
unsigned char cmd;
unsigned char tcmd;
//unsigned char totLen;
unsigned char nParam;
}tSpiHdr;
typedef struct __attribute__((__packed__))
{
uint8_t paramLen;
uint32_t param;
}tLongParam;
typedef struct __attribute__((__packed__))
{
uint8_t paramLen;
uint16_t param;
}tIntParam;
typedef struct __attribute__((__packed__))
{
uint8_t paramLen;
uint8_t param;
}tByteParam;
#endif

View File

@ -0,0 +1,72 @@
/*
wl_definitions.h - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* wl_definitions.h
*
* Created on: Mar 6, 2011
* Author: dlafauci
*/
#ifndef WL_DEFINITIONS_H_
#define WL_DEFINITIONS_H_
// Maximum size of a SSID
#define WL_SSID_MAX_LENGTH 32
// Length of passphrase. Valid lengths are 8-63.
#define WL_WPA_KEY_MAX_LENGTH 63
// Length of key in bytes. Valid values are 5 and 13.
#define WL_WEP_KEY_MAX_LENGTH 13
// Size of a MAC-address or BSSID
#define WL_MAC_ADDR_LENGTH 6
// Size of a MAC-address or BSSID
#define WL_IPV4_LENGTH 4
// Maximum size of a SSID list
#define WL_NETWORKS_LIST_MAXNUM 10
// Maxmium number of socket
#define MAX_SOCK_NUM 4
// Socket not available constant
#define SOCK_NOT_AVAIL 255
// Default state value for Wifi state field
#define NA_STATE -1
//Maximum number of attempts to establish wifi connection
#define WL_MAX_ATTEMPT_CONNECTION 10
typedef enum {
WL_NO_SHIELD = 255,
WL_IDLE_STATUS = 0,
WL_NO_SSID_AVAIL,
WL_SCAN_COMPLETED,
WL_CONNECTED,
WL_CONNECT_FAILED,
WL_CONNECTION_LOST,
WL_DISCONNECTED
} wl_status_t;
/* Encryption modes */
enum wl_enc_type { /* Values map to 802.11 encryption suites... */
ENC_TYPE_WEP = 5,
ENC_TYPE_TKIP = 2,
ENC_TYPE_CCMP = 4,
/* ... except these two, 7 and 8 are reserved in 802.11-2007 */
ENC_TYPE_NONE = 7,
ENC_TYPE_AUTO = 8
};
#endif /* WL_DEFINITIONS_H_ */

49
WiFi/utility/wl_types.h Normal file
View File

@ -0,0 +1,49 @@
/*
wl_types.h - Library for Arduino Wifi shield.
Copyright (c) 2011-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* wl_types.h
*
* Created on: Jul 30, 2010
* Author: dlafauci
*/
#ifndef _WL_TYPES_H_
#define _WL_TYPES_H_
#include <inttypes.h>
typedef enum {
WL_FAILURE = -1,
WL_SUCCESS = 1,
} wl_error_code_t;
/* Authentication modes */
enum wl_auth_mode {
AUTH_MODE_INVALID,
AUTH_MODE_AUTO,
AUTH_MODE_OPEN_SYSTEM,
AUTH_MODE_SHARED_KEY,
AUTH_MODE_WPA,
AUTH_MODE_WPA2,
AUTH_MODE_WPA_PSK,
AUTH_MODE_WPA2_PSK
};
#endif //_WL_TYPES_H_

157
WiModbusGateway.cpp Normal file
View File

@ -0,0 +1,157 @@
#include <SPI.h>
#include <WiFi.h>
#include "Metro.h"
#include "Mudbus.h"
#include "LiquidCrystal.h"
#include "ModbusApp.h"
LiquidCrystal lcd = LiquidCrystal(A0, A1, A2, A3, A4, A5);
Mudbus Mb;
//char ssid[] = "Kinderland"; // your network SSID (name)
//char pass[] = "test1234"; // your network password
char ssid[] = "MessWLAN";
char pass[] = "UNVmpwbr6heQnMQ7ykXT";
Metro tick = Metro(10000);
Metro second = Metro(1000);
uint32_t *uptime;
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
lcd.setCursor(0, 3);
lcd.print(ip); lcd.print(" ");
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
lcd.print(rssi);
}
void setup() {
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
lcd.begin(20, 4);
Serial.println("Starting ... ");
lcd.clear();
lcd.home();
lcd.print("Starting ...");
// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
lcd.setCursor(0, 1);
lcd.print("WiFi shield not present");
// don't continue:
while(true);
}
int status = WL_IDLE_STATUS;
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
lcd.setCursor(0, 1);
lcd.print("Trying: ");
lcd.print(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.println("Connected.");
lcd.setCursor(0, 2);
lcd.print("Connected.");
printWifiStatus();
delay(10000);
lcd.home();
lcd.clear();
uptime = (uint32_t*) &(Mb.R[121]); // uptime
*uptime = 0;
Mb.R[123] = 0xdead; // magic
Mb.R[124] = 0xbeef;
modbusAppBegin(&Mb);
}
void updateDisplay() {
static uint32_t lastUptime = 0;
static long lastRssi = 0;
long rssi = WiFi.RSSI();
if ((*uptime != lastUptime) ||
(rssi != lastRssi)) {
lastUptime = *uptime;
lastRssi = rssi;
lcd.home(); lcd.clear();
uint32_t days = *uptime / 86400;
uint32_t rem = *uptime % 86400;
uint32_t hours = rem / 3600;
rem = rem % 3600;
uint32_t minutes = rem / 60;
uint32_t seconds = rem % 60;
lcd.setCursor(0,0);
lcd.print(days); lcd.print("d "); lcd.print(hours); lcd.print(":");
lcd.print(minutes); lcd.print(":"); lcd.print(seconds); lcd.print(" ");
lcd.print(rssi);
lcd.setCursor(0, 1);
lcd.print(getVoltage()); lcd.print("V");
lcd.setCursor(10, 1);
lcd.print(getCurrent()); lcd.print("A");
lcd.setCursor(0, 2);
lcd.print(getFrequency()); lcd.print("Hz");
lcd.setCursor(10, 2);
lcd.print(getPower()); lcd.print("W");
lcd.setCursor(0, 3);
lcd.print(getEnergy()); lcd.print(" "); lcd.print(getNewEnergy());
lcd.setCursor(17, 3);
lcd.print("kWh");
}
}
void loop() {
modbusAppExec();
Mb.Run();
if (second.check() == 1) {
(*uptime)++;
}
updateDisplay();
}

29
WiModbusGateway.h Normal file
View File

@ -0,0 +1,29 @@
// Only modify this file to include
// - function definitions (prototypes)
// - include files
// - extern variable definitions
// In the appropriate section
#ifndef _ModbusGateway_H_
#define _ModbusGateway_H_
#include "Arduino.h"
//add your includes for the project ModbusGateway here
//end of add your includes here
#ifdef __cplusplus
extern "C" {
#endif
void loop();
void setup();
#ifdef __cplusplus
} // extern "C"
#endif
//add your function definitions for the project ModbusGateway here
//Do not add code below this line
#endif /* _ModbusGateway_H_ */

106
gateway.cpp Normal file
View File

@ -0,0 +1,106 @@
/*
* gateway.cpp
*
* Created on: 26.10.2014
* Author: wn
*/
#include "gateway.h"
#include "Streaming.h"
void Gateway::prepareAssignments() {
for (uint8_t i = 0; i < TOTAL_NO_OF_PACKETS; i++) {
m_gatewayAssignments[i].id = 0;
m_gatewayAssignments[i].function = 0;
m_gatewayAssignments[i].address = 0;
m_gatewayAssignments[i].data = 0;
m_gatewayAssignments[i].mudbusIndex = 0;
}
}
void Gateway::assignPacket(uint8_t packetIdx, uint8_t id, uint8_t function, uint16_t address, uint16_t data, uint16_t mudbusIdx) {
m_packets[packetIdx].id = id;
m_packets[packetIdx].function = function;
m_packets[packetIdx].address = address;
m_packets[packetIdx].data = data;
m_packets[packetIdx].register_array = (unsigned int*) &(m_mudbus->R[mudbusIdx]);
m_packets[packetIdx].connection = 1;
m_packets[packetIdx].connectionValid = &(m_mudbus->C[mudbusIdx + CONNECTION_STATUS_OFFSET]);
m_packets[packetIdx].valueValid = &(m_mudbus->C[mudbusIdx + VALUE_STATUS_OFFSET]);
}
void Gateway::begin() {
for (uint8_t i = 0; i < TOTAL_NO_OF_PACKETS; i++) {
if (m_gatewayAssignments[i].id != 0) {
assignPacket(i, m_gatewayAssignments[i].id, m_gatewayAssignments[i].function, m_gatewayAssignments[i].address,
m_gatewayAssignments[i].data, m_gatewayAssignments[i].mudbusIndex);
} else {
m_packets[i].connection = 0;
}
}
// modbus_configure(&Serial2, MODBUS_BAUD, SERIAL_8N2, MODBUS_TIMEOUT, MODBUS_SCANRATE, MODBUS_RETRY_COUNT, MODBUS_TX_ENABLE_PIN, m_packets, TOTAL_NO_OF_PACKETS);
}
void Gateway::reactivate() {
for (uint8_t i = 0; i < TOTAL_NO_OF_PACKETS; i++) {
if (m_gatewayAssignments[i].id != 0) {
if (! m_packets[i].connectionValid) {
m_packets[i].connection = 1;
Serial << "Reactivated assignment " << i << endl;
}
}
}
}
void Gateway::show() {
for (uint8_t i = 0; i < TOTAL_NO_OF_PACKETS; i++) {
if (m_gatewayAssignments[i].id != 0) {
Serial << i << ": ID: " << m_gatewayAssignments[i].id << ", Func: " << m_gatewayAssignments[i].function << ", Addr: " << _HEX(m_gatewayAssignments[i].address) <<
", Len: " << m_gatewayAssignments[i].data << ", MbIdx: " << m_gatewayAssignments[i].mudbusIndex << endl;
Serial << " " << "ConnectionStatus: " << m_mudbus->C[m_gatewayAssignments[i].mudbusIndex + CONNECTION_STATUS_OFFSET] <<
", ValueStatus: " << m_mudbus->C[m_gatewayAssignments[i].mudbusIndex + VALUE_STATUS_OFFSET] << endl;
Serial << " ";
for (uint8_t j = 0; j < m_gatewayAssignments[i].data; j++) {
Serial << _HEX(((unsigned int) m_mudbus->R[m_gatewayAssignments[i].mudbusIndex + j])) << " ";
}
Serial << endl;
}
}
}
void Gateway::assign(uint8_t id, uint8_t function, uint16_t address, uint16_t data) {
uint16_t nextMudbusIndex = 0;
for (uint8_t i = 0; i < TOTAL_NO_OF_PACKETS; i++) {
if (m_gatewayAssignments[i].id != 0) {
nextMudbusIndex += m_gatewayAssignments[i].data;
} else {
m_gatewayAssignments[i].id = id;
m_gatewayAssignments[i].function = function;
m_gatewayAssignments[i].address = address;
m_gatewayAssignments[i].data = data;
m_gatewayAssignments[i].mudbusIndex = nextMudbusIndex;
assignPacket(i, m_gatewayAssignments[i].id, m_gatewayAssignments[i].function, m_gatewayAssignments[i].address,
m_gatewayAssignments[i].data, m_gatewayAssignments[i].mudbusIndex);
break;
}
}
}
void Gateway::exec() {
}

56
gateway.h Normal file
View File

@ -0,0 +1,56 @@
/*
* gateway.h
*
* Created on: 26.10.2014
* Author: wn
*/
#ifndef GATEWAY_H_
#define GATEWAY_H_
#include <Arduino.h>
#include "SimpleModbusMaster.h"
#include "Mudbus.h"
const uint8_t TOTAL_NO_OF_PACKETS = 8;
const uint32_t MODBUS_BAUD = 1200;
const uint16_t MODBUS_TIMEOUT = 10000;
const uint16_t MODBUS_SCANRATE = 1000;
const uint8_t MODBUS_RETRY_COUNT = 25;
const uint8_t MODBUS_TX_ENABLE_PIN = 2;
const uint16_t CONNECTION_STATUS_OFFSET = 0;
const uint16_t VALUE_STATUS_OFFSET = 0x100;
struct GatewayAssignment {
uint8_t id;
uint8_t function;
uint16_t address;
uint16_t data;
uint16_t mudbusIndex;
};
class Gateway {
public:
Gateway(Mudbus *mudbus) : m_mudbus(mudbus) {};
void prepareAssignments();
void begin();
void exec();
void show();
void assign(uint8_t id, uint8_t function, uint16_t address, uint16_t data);
void reactivate();
private:
Mudbus *m_mudbus;
Packet m_packets[TOTAL_NO_OF_PACKETS];
GatewayAssignment m_gatewayAssignments[TOTAL_NO_OF_PACKETS];
void assignPacket(uint8_t packetIdx, uint8_t id, uint8_t function, uint16_t address, uint16_t data, uint16_t mudbusIdx);
};
#endif /* GATEWAY_H_ */

2
spec.d Normal file
View File

@ -0,0 +1,2 @@
spec.o: \
/Users/wn/Documents/workspace/.metadata/.plugins/org.eclipse.cdt.managedbuilder.core/spec.C