Check-in [b228fa2c9b]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Разработаны эл. схемы, спецификации. Добавлен код Димы.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:b228fa2c9bd5a6b595bba23f1fb4d1f82422c2f3
User & Date: zhekasakun 2016-09-17 18:54:40
Context
2016-09-17
22:14
Исправлены ошибки в схемах. Закончен расчет стоимости покупных изделий. check-in: 223d4ad799 user: zhekasakun tags: trunk
18:54
Разработаны эл. схемы, спецификации. Добавлен код Димы. check-in: b228fa2c9b user: zhekasakun tags: trunk
2016-08-21
16:54
initial empty check-in check-in: 6c28643cf6 user: zhekasakun tags: trunk
Changes

Added doc/draws/schematic.dwg.

cannot compute difference between binary files

Added doc/draws/Схемы.vsd.

cannot compute difference between binary files

Added doc/draws/Эскиз_пожарного_робота.bak.

cannot compute difference between binary files

Added doc/draws/Эскиз_пожарного_робота.dwg.

cannot compute difference between binary files

Added doc/pozharny_robot.gan.











































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?xml version="1.0" encoding="UTF-8"?><project name="Пожарный робот" company="" webLink="http://" view-date="2016-08-03" view-index="0" gantt-divider-location="451" resource-divider-location="300" version="2.7.2" locale="ru">
    <description><![CDATA[Проект для Бориса из Артемовска.]]></description>
    <view zooming-state="default:0" id="gantt-chart">
        <field id="tpd3" name="Название" width="59" order="0"/>
        <field id="tpd4" name="Дата начала" width="17" order="1"/>
        <field id="tpd5" name="Дата окончания" width="22" order="2"/>
    </view>
    <view id="resource-table">
        <field id="0" name="Имя" width="50" order="0"/>
        <field id="1" name="Стандартная роль" width="49" order="1"/>
    </view>
    <!-- -->
    <calendars>
        <day-types>
            <day-type id="0"/>
            <day-type id="1"/>
            <default-week id="1" name="default" sun="1" mon="0" tue="0" wed="0" thu="0" fri="0" sat="0"/>
            <only-show-weekends value="false"/>
            <overriden-day-types/>
            <days/>
        </day-types>
    </calendars>
    <tasks empty-milestones="true">
        <taskproperties>
            <taskproperty id="tpd0" name="type" type="default" valuetype="icon"/>
            <taskproperty id="tpd1" name="priority" type="default" valuetype="icon"/>
            <taskproperty id="tpd2" name="info" type="default" valuetype="icon"/>
            <taskproperty id="tpd3" name="name" type="default" valuetype="text"/>
            <taskproperty id="tpd4" name="begindate" type="default" valuetype="date"/>
            <taskproperty id="tpd5" name="enddate" type="default" valuetype="date"/>
            <taskproperty id="tpd6" name="duration" type="default" valuetype="int"/>
            <taskproperty id="tpd7" name="completion" type="default" valuetype="int"/>
            <taskproperty id="tpd8" name="coordinator" type="default" valuetype="text"/>
            <taskproperty id="tpd9" name="predecessorsr" type="default" valuetype="text"/>
        </taskproperties>
        <task id="11" name="Выбрать систему пожаротушения" color="#8cb6ce" meeting="false" start="2016-08-04" duration="1" complete="100" expand="true">
            <depend id="1" type="2" difference="0" hardness="Strong"/>
        </task>
        <task id="10" name="Разработать датчик огня" color="#8cb6ce" meeting="false" start="2016-08-04" duration="1" complete="100" expand="true">
            <depend id="0" type="3" difference="0" hardness="Strong"/>
            <depend id="1" type="2" difference="0" hardness="Strong"/>
        </task>
        <task id="0" name="Составить принципиальную схему" color="#8cb6ce" meeting="false" start="2016-08-04" duration="1" complete="0" expand="true">
            <depend id="2" type="2" difference="0" hardness="Strong"/>
            <depend id="7" type="2" difference="0" hardness="Strong"/>
            <depend id="12" type="2" difference="0" hardness="Strong"/>
        </task>
        <task id="1" name="Определить общую компоновку робота" color="#8cb6ce" meeting="false" start="2016-08-05" duration="1" complete="0" expand="true">
            <depend id="4" type="2" difference="0" hardness="Strong"/>
        </task>
        <task id="2" name="Определить общую компоновку платы" color="#8cb6ce" meeting="false" start="2016-08-05" duration="1" complete="0" expand="true">
            <depend id="3" type="2" difference="0" hardness="Strong"/>
        </task>
        <task id="3" name="Разработать чертеж платы" color="#8cb6ce" meeting="false" start="2016-08-06" duration="1" complete="0" expand="true">
            <depend id="4" type="2" difference="0" hardness="Strong"/>
        </task>
        <task id="4" name="Выполнить монтаж робота" color="#8cb6ce" meeting="false" start="2016-08-08" duration="2" complete="0" expand="true"/>
        <task id="6" name="Доработать ПО робота" meeting="false" start="2016-08-04" duration="3" complete="0" expand="true">
            <task id="5" name="Изучить ПО робота" color="#8cb6ce" meeting="false" start="2016-08-04" duration="2" complete="0" expand="true">
                <depend id="7" type="2" difference="0" hardness="Strong"/>
                <depend id="8" type="2" difference="0" hardness="Strong"/>
                <depend id="9" type="2" difference="0" hardness="Strong"/>
                <depend id="12" type="2" difference="0" hardness="Strong"/>
            </task>
            <task id="9" name="Переделать под новый драйвер" color="#8cb6ce" meeting="false" start="2016-08-06" duration="1" complete="0" expand="true"/>
            <task id="8" name="Убрать измерение тока" color="#8cb6ce" meeting="false" start="2016-08-06" duration="1" complete="0" expand="true"/>
            <task id="7" name="Добавить команду полива" color="#8cb6ce" meeting="false" start="2016-08-06" duration="1" complete="0" expand="true"/>
            <task id="12" name="Добавить датчик огня" color="#8cb6ce" meeting="false" start="2016-08-06" duration="1" complete="0" expand="true"/>
        </task>
        <task id="13" name="Разработать документацию" meeting="false" start="2016-08-04" duration="4" complete="0" expand="true">
            <task id="14" name="Разработать мат. модель" color="#8cb6ce" meeting="false" start="2016-08-04" duration="1" complete="0" expand="true">
                <depend id="15" type="2" difference="0" hardness="Strong"/>
            </task>
            <task id="15" name="Написать 30 стр." color="#8cb6ce" meeting="false" start="2016-08-05" duration="3" complete="0" expand="true"/>
        </task>
    </tasks>
    <resources>
        <resource id="0" name="Сакун" function="Default:1" contacts="" phone="">
            <rate name="standard" value="20"/>
        </resource>
    </resources>
    <allocations>
        <allocation task-id="11" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
        <allocation task-id="10" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
        <allocation task-id="0" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
        <allocation task-id="1" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
        <allocation task-id="2" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
        <allocation task-id="3" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
        <allocation task-id="4" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
        <allocation task-id="5" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
        <allocation task-id="9" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
        <allocation task-id="8" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
        <allocation task-id="7" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
        <allocation task-id="12" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
        <allocation task-id="14" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
        <allocation task-id="15" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
    </allocations>
    <vacations/>
    <taskdisplaycolumns>
        <displaycolumn property-id="tpd10" order="-1" width="75" visible="false"/>
        <displaycolumn property-id="tpd7" order="-1" width="75" visible="false"/>
        <displaycolumn property-id="tpd3" order="0" width="268" visible="true"/>
        <displaycolumn property-id="tpd4" order="1" width="80" visible="true"/>
        <displaycolumn property-id="tpd5" order="2" width="99" visible="true"/>
        <displaycolumn property-id="tpd6" order="-1" width="75" visible="false"/>
        <displaycolumn property-id="tpd13" order="-1" width="75" visible="false"/>
        <displaycolumn property-id="tpd8" order="-1" width="75" visible="false"/>
        <displaycolumn property-id="tpd2" order="-1" width="75" visible="false"/>
        <displaycolumn property-id="tpd9" order="-1" width="75" visible="false"/>
        <displaycolumn property-id="tpd1" order="-1" width="75" visible="false"/>
        <displaycolumn property-id="tpd12" order="-1" width="75" visible="false"/>
        <displaycolumn property-id="tpd11" order="-1" width="75" visible="false"/>
        <displaycolumn property-id="tpd0" order="-1" width="75" visible="false"/>
    </taskdisplaycolumns>
    <previous/>
    <roles roleset-name="Default"/>
</project>

Added doc/Закупки.xlsx.

cannot compute difference between binary files

Added doc/Компоненты.ods.

cannot compute difference between binary files

Added doc/Пояснительная записка.docx.

cannot compute difference between binary files

Added src/Communication_Atmega8_Studio5/Communication_Atmega8_Studio5.atsln.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Microsoft Visual Studio Solution File, Format Version 11.00
# AvrStudio Solution File, Format Version 11.00
Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "Communication_Atmega8_Studio5", "Communication_Atmega8_Studio5\Communication_Atmega8_Studio5.cproj", "{8556C5FE-C6A6-4A11-8850-7AAA06ACBFAA}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|AVR = Debug|AVR
		Release|AVR = Release|AVR
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{8556C5FE-C6A6-4A11-8850-7AAA06ACBFAA}.Debug|AVR.ActiveCfg = Debug|AVR
		{8556C5FE-C6A6-4A11-8850-7AAA06ACBFAA}.Debug|AVR.Build.0 = Debug|AVR
		{8556C5FE-C6A6-4A11-8850-7AAA06ACBFAA}.Release|AVR.ActiveCfg = Release|AVR
		{8556C5FE-C6A6-4A11-8850-7AAA06ACBFAA}.Release|AVR.Build.0 = Release|AVR
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
EndGlobal

Added src/Communication_Atmega8_Studio5/Communication_Atmega8_Studio5.atsuo.

cannot compute difference between binary files

Added src/Communication_Atmega8_Studio5/Communication_Atmega8_Studio5/Communication_Atmega8_Studio5.c.



































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
 * Communication_Atmega8_Studio5.c
 *
 * Created: 23.01.2016 17:39:45
 *  Author: Dimon
 */ 

#include <avr/io.h>
#include "src/ControllerPC.h"

int main(void)
{
    while(1)
    {
        controllerPC ();
    }
}

Added src/Communication_Atmega8_Studio5/Communication_Atmega8_Studio5/Communication_Atmega8_Studio5.cproj.





































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectVersion>5.1</ProjectVersion>
    <ToolchainName>com.Atmel.AVRGCC8</ToolchainName>
    <ProjectGuid>{8556c5fe-c6a6-4a11-8850-7aaa06acbfaa}</ProjectGuid>
    <avrdevice>ATmega8</avrdevice>
    <avrdeviceseries>none</avrdeviceseries>
    <OutputType>Executable</OutputType>
    <Language>C</Language>
    <OutputFileName>$(MSBuildProjectName)</OutputFileName>
    <OutputFileExtension>.elf</OutputFileExtension>
    <OutputDirectory>$(MSBuildProjectDirectory)\$(Configuration)</OutputDirectory>
    <AssemblyName>Communication_Atmega8_Studio5</AssemblyName>
    <Name>Communication_Atmega8_Studio5</Name>
    <RootNamespace>Communication_Atmega8_Studio5</RootNamespace>
    <ToolchainFlavour>Native</ToolchainFlavour>
    <AsfVersion>2.11.1</AsfVersion>
    <avrtoolinterface />
    <avrtool>com.atmel.avrdbg.tool.simulator</avrtool>
    <com_atmel_avrdbg_tool_simulator>
      <ToolType xmlns="">com.atmel.avrdbg.tool.simulator</ToolType>
      <ToolName xmlns="">AVR Simulator</ToolName>
      <ToolNumber xmlns="">
      </ToolNumber>
      <Channel xmlns="">
        <host>127.0.0.1</host>
        <port>49489</port>
        <ssl>False</ssl>
      </Channel>
    </com_atmel_avrdbg_tool_simulator>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
    <ToolchainSettings>
      <AvrGcc>
        <avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
        <avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
        <avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level>
        <avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
        <avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
        <avrgcc.compiler.optimization.DebugLevel>None</avrgcc.compiler.optimization.DebugLevel>
        <avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
        <avrgcc.linker.libraries.Libraries>
          <ListValues>
            <Value>m</Value>
          </ListValues>
        </avrgcc.linker.libraries.Libraries>
      </AvrGcc>
    </ToolchainSettings>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
    <ToolchainSettings>
      <AvrGcc>
        <avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
        <avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
        <avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
        <avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
        <avrgcc.compiler.optimization.level>Optimize (-O1)</avrgcc.compiler.optimization.level>
        <avrgcc.compiler.optimization.DebugLevel>Default (-g2)</avrgcc.compiler.optimization.DebugLevel>
        <avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
        <avrgcc.assembler.debugging.DebugLevel>Default (-g2)</avrgcc.assembler.debugging.DebugLevel>
        <avrgcc.linker.libraries.Libraries>
          <ListValues>
            <Value>m</Value>
          </ListValues>
        </avrgcc.linker.libraries.Libraries>
      </AvrGcc>
    </ToolchainSettings>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="Communication_Atmega8_Studio5.c">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\ControllerPC.c">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\ControllerPC.h">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\RFM.c">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\RFM.h">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\UART.c">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\UART.h">
      <SubType>compile</SubType>
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <Folder Include="src\" />
  </ItemGroup>
  <Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
</Project>

Added src/Communication_Atmega8_Studio5/Communication_Atmega8_Studio5/src/ControllerPC.c.













































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
Студенческий клуб разработчиков компьютерных систем 
			Проект "Mr.General"

Модуль предназначен для управления Обменом сообщениями клиента с 
сервером.

Программа написана для микроконтроллера AVR ATmega 16.
Тактовая частота процессора - 8 МГц.

Для компиляции использовались инструменты Atmel AVR Studio 5
(Version 5.1.208).

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdio.h>
#include <string.h>
#include <avr/interrupt.h>
#include "UART.h"
#include "SPI.h"
#include "RFM.h"
#include "ControllerPC.h"


#define  outLED() DDRD |= (1<<6)
#define  offLED() PORTD &= ~(1<<6)
#define  onLED() PORTD |= (1<<6)

void messegeAgent(char *msg);
uint8_t connected_RFM = 0;

void controllerPC ()
{
	outLED();
	onLED();
	uint32_t m,n;
	for(n = 0; n < 10; n++)
	{	
		offLED();
		for(m = 0; m < 10000; m++);
		onLED();
		for(m = 0; m < 10000; m++);	
	}
	
	sei();
	initUART();
	sendStrUART("BS connect");
	initSPI(MASTER);
	initRFM(RECEIVE);
	if(getStatusReg() == 14){
		connected_RFM = 1;
		sendStrUART("RFM connect");	
	}
	else	sendStrUART("RFM disconnect");	
    while(1)
    {
		static uint32_t i = 0, state_led = 0;
		
		if (i++ > 10000)
		{
			switch (state_led){
				case 0:
					offLED();
					state_led = 1;
					break;
				case 1:
					onLED();
					state_led = 0;
					break;	
			}
			i = 0;
		}
		
		//sendStrUART(getStrUART());
		messegeAgent(getStrUART());
		sendStrUART(getStrRFM());
        if(!processRFM()){
			sendStrUART("no signal with robot");
		}
		processTransmitUART();
    }
}

void messegeAgent(char *msg)
{
	if(msg != NULL){
		if(strcmp(msg,"statusRFM") == 0){
			uint8_t stat;
			stat = getStatusReg();
			if((stat & (1<<1)) && (stat & (1<<2)) && (stat & (1<<3)))
				sendStrUART("RX FIFO empty");
			else {
				if((stat & (1<<1)) && (stat & (1<<2)) && !(stat & (1<<3)) )
					sendStrUART("RX FIFO not use");
				else
					sendStrUART("RX FIFO reading");
			}
			if(stat & (1<<0))
				sendStrUART("TX FIFO full");
			else
				sendStrUART("TX FIFO empty");
			if(stat & (1<<4))
				sendStrUART("Maximum number of TX retransmits");
			if(stat & (1<<5))
				sendStrUART("Data Sent TX FIFO interrupt");
			if(stat & (1<<6))
				sendStrUART("Data Ready RX FIFO interrupt");
			return;	
		}
		if(strcmp(msg,"statreg") == 0){
			uint8_t stat = 0;
			stat = getStatusReg();
			int tmp_stat;
			tmp_stat = stat;
			static char stat_str[10];
			sprintf(stat_str,"%d",tmp_stat);
			sendStrUART(stat_str);
			return;
		}
		if(strcmp(msg,"connectRFM") == 0){
			if (connected_RFM)
				sendStrUART("RFM connect");
			else
				sendStrUART("RFM disconnect");
			return;
		}
		sendStrRFM(msg);				
	}
}

Added src/Communication_Atmega8_Studio5/Communication_Atmega8_Studio5/src/ControllerPC.h.





































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
	Студенческий клуб разработчиков компьютерных систем 
				Проект "Mr.General"

Это заголовочный файл к файлу ControllerPC.c

История изменений: 08.11.2014 - создан;

**********************************************************************/
#ifndef CONTROLLER_PC
#define CONTROLLER_PC

void controllerPC ();

#endif

Added src/Communication_Atmega8_Studio5/Communication_Atmega8_Studio5/src/RFM.c.

















































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
Студенческий клуб разработчиков компьютерных систем 
			Проект "Mr.General"

Модуль предназначен для обмена данными по RFM.

Программа написана для микроконтроллера AVR ATmega 16.
Тактовая частота процессора - 8 МГц.

Для компиляции использовались инструменты Atmel AVR Studio 5
(Version 5.1.208).

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdint.h>
#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
//#include "SPI.h"
#include "RFM.h"
#include "UART.h"

//#define DEBUG

#define SIZE_MESSEGE 30
#define SIZE_BUFRX 5
#define SIZE_BUFTX 10

#define IRQ 5
#define CE 1
#define CS 2
#define SS 2
#define MOSI 3
#define SCK 5

#define DDR_SPI DDRB

#define PIN_RFM PINC
#define PORT_RFM PORTC
#define DDR_RFM DDRC

#define  outCE() DDR_RFM |= (1<<CE)
#define  lowCE() PORT_RFM &= ~(1<<CE)
#define  highCE() PORT_RFM |= (1<<CE)

#define  outCS() DDR_RFM |= (1<<CS)
#define  lowCS() PORT_RFM &= ~(1<<CS)
#define  highCS() PORT_RFM |= (1<<CS)

#define MASTER 0
#define SLAVE 1

uint8_t getSPI();
void sendSPI(uint8_t cData);
void initSPI(uint8_t mode);

void sendByteRFM(uint8_t out_data);
uint8_t getByteRFM();
uint8_t isTransmitRFM();
uint8_t isReceiveRFM();
uint8_t processTransmitRFM();
void processReceiveRFM();
void addTransmitRFM(char *add_str);
char* takeTransmitRFM();

static char *pointerTX_RFM = NULL;
static char *buffer_TX_RFM[SIZE_BUFTX] = {NULL};
static uint8_t empty_TX_RFM = 0;
static uint8_t take_TX_RFM = 0;

static char bufferRX_RFM[SIZE_BUFRX][SIZE_MESSEGE];
static uint8_t busy_str_RX_RFM = 0;	
static uint8_t empty_str_RX_RFM = 0;

uint8_t transmitingRFM = 0;
uint8_t receivingRFM = 0;


void addTransmitRFM(char *add_str)
{
	buffer_TX_RFM[empty_TX_RFM++] = add_str;
	if (empty_TX_RFM >= SIZE_BUFTX){
		empty_TX_RFM = 0;
	}	
}


// Взятие строки из буффера для передачи
char* takeTransmitRFM()
{ 
	if(take_TX_RFM >= SIZE_BUFTX){
		take_TX_RFM = 0; 
	}	
	if(take_TX_RFM == empty_TX_RFM){
		return NULL;
	}	
	return  buffer_TX_RFM[take_TX_RFM++];
}

void sendStrRFM (char *str)
{
	#ifdef DEBUG
		sendingStrUART("sendStrRFM 1");
	#endif
	if(str != NULL){
		if(!receivingRFM){
			if(!transmitingRFM){
				#ifdef DEBUG
					sendingStrUART("sendStrRFM 2");
				#endif
				setModeRFM(TRANSMIT);
				#ifdef DEBUG
					sendingStrUART("sendStrRFM 3");
				#endif
				pointerTX_RFM = str;
				sendByteRFM(*pointerTX_RFM);
				pointerTX_RFM++;
				transmitingRFM = 1;
				#ifdef DEBUG
					sendingStrUART(" sendStrRFM END");
				#endif
			}
			else{
				#ifdef DEBUG
					sendingStrUART(" sendStrRFM else 1");
				#endif
				addTransmitRFM(str);
				#ifdef DEBUG
					sendingStrUART(" sendStrRFM else END");
				#endif
			}
		}	
	}
}

void sendByteRFM(uint8_t out_data)
{
	/*if (getStatusReg() & (1<<TX_DS_BIT)){
		sendCommandRFM((W_REGISTER_CMD | STATUS_REG), (1<<TX_DS_BIT));
	}*/	
	lowCS();
	//PORTD &= ~(1<<SS);
	sendSPI(W_TX_PAYLOAD);
	sendSPI(out_data);
	highCS();		
	//PORTD |= (1<<SS);
}
					
uint8_t processRFM()
{
	if(transmitingRFM){
		if(!processTransmitRFM()){
			return 0;
		}
	}
	else {
		if(isReceiveRFM()){
			processReceiveRFM();
		}	
	}
	return 1;	
}

// Управление процессом передачи данных
uint8_t processTransmitRFM()
{
	if(isTransmitRFM()){
		sendByteRFM(*pointerTX_RFM);
		if (*pointerTX_RFM == '\0'){
			pointerTX_RFM = takeTransmitRFM();
			if(pointerTX_RFM == NULL){
				//uint16_t ctr_TX = 0;
				while(!isTransmitRFM()){
					/*if(ctr_TX++ < 10000){
						setModeRFM(RECEIVE);
						return 0;
					}*/
					;
				}					
				setModeRFM(RECEIVE);
				transmitingRFM = 0;
			}
		} 
		else {
			pointerTX_RFM++;
		}	
	}
	else{
		if (getStatusReg() & (1<<MAX_RT_BIT)){
			sendCommandRFM ((W_REGISTER_CMD | STATUS_REG), (1<<MAX_RT_BIT));
			sendSPI(FLUSH_TX); 
			setModeRFM(RECEIVE);
			transmitingRFM = 0;
			return 0;
		}
	}
	return 1;
}

void processReceiveRFM()
{
	static uint8_t empty_char_RX = 0;
	bufferRX_RFM[empty_str_RX_RFM][empty_char_RX] = getByteRFM();	
	if (bufferRX_RFM[empty_str_RX_RFM][empty_char_RX] == '\0'){
		receivingRFM = 0;
		empty_char_RX = 0;
		if (++empty_str_RX_RFM >= SIZE_BUFRX){
			empty_str_RX_RFM = 0;
		}	
	}
	else {
		++empty_char_RX;
		receivingRFM = 1;
	}
}

char *getStrRFM ()
{	
	if(busy_str_RX_RFM >= SIZE_BUFRX){
		busy_str_RX_RFM = 0; 
	}	
	if(busy_str_RX_RFM == empty_str_RX_RFM){
		return NULL;
	}	
	return bufferRX_RFM[busy_str_RX_RFM++];
}	

uint8_t isTransmitRFM()
{	
	if (getStatusReg() & (1<<TX_DS_BIT)){
	//if ((PINC &(1<<IRQ)) == 0){	
		sendCommandRFM ((W_REGISTER_CMD | STATUS_REG), (1<<TX_DS_BIT));
		return 1;
	}
	return 0;		
}

uint8_t isReceiveRFM()
{
	//if (getStatusReg() & (1<<RX_DR_BIT)){	
	if ((PIN_RFM &(1<<IRQ)) == 0){
		// Очищяем флаг прерывания при приеме сообщения в RFM
		sendCommandRFM ((W_REGISTER_CMD | STATUS_REG), (1<<RX_DR_BIT));
		return 1;
	}
	else return 0;
}

void sendCommandRFM(uint8_t first_comand, uint8_t second_comand)
{
	#ifdef DEBUG
		sendingStrUART("  sendCommandRFM 1");
	#endif
	
	lowCS();
	sendSPI(first_comand);
	
	#ifdef DEBUG
		sendingStrUART("  sendCommandRFM 2");
	#endif
	
	sendSPI(second_comand);
	
	highCS();
	
	#ifdef DEBUG
		sendingStrUART("  sendCommandRFM END");
	#endif
}


uint8_t getStatusReg()
{
	uint8_t status = 0;
	lowCS();
	SPDR = 0xFF;
	while(!(SPSR & (1<<SPIF)));
	status = getSPI();
	highCS();
	return status;	
}

uint8_t getByteRFM()
{
	uint8_t data = 0;
	lowCS();
	// Отправляем команду получить данные RFM
	sendSPI(R_RX_PAYLOAD);
	sendSPI(0xFF);
	data = getSPI();
	highCS();
	return 	data;
}	
///////////

void initRFM(uint8_t init_modeRFM)
{
	switch (init_modeRFM)
	{
		case RECEIVE:
					outCE();
					lowCE();
					// Устанавливаем количество байт приема
					sendCommandRFM((W_REGISTER_CMD | RX_PW_P0_REG), 0x1);	
					// Включаем питание настраеваем на приемник (reciever)
					sendCommandRFM((W_REGISTER_CMD | CONFIG_REG),((1<<EN_CRC_BIT)|(1<<PWR_UP_BIT)|(1<<PRIM_RX_BIT)));
					highCE();
					break;
		case TRANSMIT:
					outCE();
					//DDRB |= (1<<CE);
					// Включаем питание настраеваем на передатчик (transmiter)
					sendCommandRFM((W_REGISTER_CMD | CONFIG_REG),((1<<EN_CRC_BIT) | (1<<PWR_UP_BIT)));
					highCE();
					break;
	}				
}	


void setModeRFM(uint8_t modeRFM)
{
	switch (modeRFM)
	{
		case RECEIVE:
					lowCE();
					sendCommandRFM((W_REGISTER_CMD | CONFIG_REG),(0<<PWR_UP_BIT));
					sendCommandRFM((W_REGISTER_CMD | RX_PW_P0_REG), 0x1);	
					// Включаем питание настраеваем на приемник (reciever)
					sendCommandRFM((W_REGISTER_CMD | CONFIG_REG),((1<<EN_CRC_BIT)|(1<<PWR_UP_BIT)|(1<<PRIM_RX_BIT)));
					highCE();
					
					#ifdef DEBUG
						sendingStrUART("RFM Receive");
					#endif
					break;
		case TRANSMIT:
					
					lowCE();
					#ifdef DEBUG
						sendingStrUART("setModeRFM TX 1");
					#endif
					
					sendCommandRFM((W_REGISTER_CMD | CONFIG_REG),(0<<PWR_UP_BIT));
					
					#ifdef DEBUG
						sendingStrUART("setModeRFM TX 2");
					#endif
					
					// Включаем питание настраеваем на передатчик (transmiter)
					sendCommandRFM((W_REGISTER_CMD | CONFIG_REG),((1<<EN_CRC_BIT)|(1<<PWR_UP_BIT)|(0<<PRIM_RX_BIT)));
					
					#ifdef DEBUG
						sendingStrUART("setModeRFM TX 3");
					#endif
					
					highCE();
		
					#ifdef DEBUG
						sendingStrUART("setModeRFM TX END");
					#endif
					break;
	}
}

//Инициализация SPI
void initSPI(uint8_t mode)
{
	switch (mode)
	{
		
		case MASTER:
			/* Set MOSI, SCK, SS output, all others input */
			DDR_SPI |= 1<<MOSI | 1<<SCK | 1<<SS;
			outCS();
			highCS();
			/*Инициализация SPI на ведущего (Master), разрешение работы SPI */
			SPCR = (1<<SPE)|(1<<MSTR);	
			break;
		case SLAVE:
			DDR_SPI |= 1<<6 | 1<<4;
			//Инициализация SPI на ведомого (Slave)
			SPCR = (1<<SPE);
			break;
	}
}

//Отправка данных
void sendSPI(uint8_t cData)
{
	//cli();
	
	#ifdef DEBUG
		sendingStrUART("   sendSPI 1");
	#endif
	
	// Start transmission
	SPDR = cData;
	// Wait for transmission complete
	while(!(SPSR & (1<<SPIF)));
	
	#ifdef DEBUG
		sendingStrUART("    sendSPI END");
	#endif
	
	//sei();
}

//Прием данных
uint8_t getSPI()
{
	//cli();
	while(!(SPSR & (1<<SPIF)));
	//Return data register
	return SPDR;
	//sei();
}



Added src/Communication_Atmega8_Studio5/Communication_Atmega8_Studio5/src/RFM.h.





























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
	Студенческий клуб разработчиков компьютерных систем 
				Проект "Mr.General"

Это заголовочный файл к файлу RFM.c

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdint.h>
#ifndef RFM_H
#define RFM_H




#define RECEIVE 0
#define TRANSMIT 1

#define FLUSH_RX 0xE2
#define FLUSH_TX 0xE1
#define W_TX_PAYLOAD_NOACK 0xB0
#define W_REGISTER_CMD 0x20
#define R_REGISTER_CMD 0

#define RX_PW_P0_REG 0x11

#define CONFIG_REG 0x0
#define PRIM_RX_BIT 0
#define PWR_UP_BIT 1
#define EN_CRC_BIT 3

#define STATUS_REG 0x7
#define RX_DR_BIT 6
#define TX_DS_BIT 5 
#define MAX_RT_BIT 4

#define R_RX_PAYLOAD 0x61
#define W_TX_PAYLOAD 0xA0

/*
Инициализация RFM.
*/
void initRFM(uint8_t init_modeRFM);

/*
Выбор режима RFM.
modeRFM - режим.
*/
void setModeRFM(uint8_t modeRFM);

/*
Отправка данных. 
str - указатель на строку для отправки по RFM.
*/
void sendStrRFM (char *str);

/*
Прием данных. 
return - указатель на строку пришедшую по RFM.
*/
char *getStrRFM ();

// Управление процессом обмена данными
uint8_t processRFM();

//Отправка команд RFM.
void sendCommandRFM(uint8_t first_comand, uint8_t second_comand);

//Получение статусного регистра RFM.
uint8_t getStatusReg();


#endif

Added src/Communication_Atmega8_Studio5/Communication_Atmega8_Studio5/src/SPI.c.









































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
Студенческий клуб разработчиков компьютерных систем 
			Проект "Mr.General"

Модуль предназначен для обмена данными по SPI.

Программа написана для микроконтроллера AVR ATmega 16.
Тактовая частота процессора - 8 МГц.

Для компиляции использовались инструменты Atmel AVR Studio 5
(Version 5.1.208).

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdint.h>
#include <avr/io.h>
#include "SPI.h"

//Инициализация SPI
void initSPI(uint8_t mode)
{
	switch (mode)
	{
		
		case MASTER:
					/* Set MOSI, SCK, SS output, all others input */
					DDRB |= 1<<MOSI | 1<<SCK;
					outCS();
					//setPin (B,SS);
					//highCS();
					highCS();
					//PORTD &= ~(1<<SS);
					/*Инициализация SPI в регистре SPCR (SPI CONTROL REGISTER) на ведущего (Master), разрешение работы SPI */
					SPCR = (1<<SPE)|(1<<MSTR);
					break;
		case SLAVE:
					/* Set MISO output, all others input */
					DDRB |= 1<<6 | 1<<4;
					//Инициализация SPI в регистре SPCR (SPI CONTROL REGISTER) на ведомого (Slave)
					SPCR = (1<<SPE);
					break;			
	}
}

//Отправка данных
void sendSPI(uint8_t cData)
{
	// Start transmission 
	SPDR = cData;
	// Wait for transmission complete 
	while(!(SPSR & (1<<SPIF)));
}

//Прием данных
uint8_t getSPI()
{
	while(!(SPSR & (1<<SPIF)));
	//Return data register 
	return SPDR;
}	



Added src/Communication_Atmega8_Studio5/Communication_Atmega8_Studio5/src/SPI.h.































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
	Студенческий клуб разработчиков компьютерных систем 
				Проект "Mr.General"

Это заголовочный файл к файлу SPI.c

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdint.h>
#ifndef SPI_H 
#define SPI_H

#define CS 2
#define MOSI 3
#define SCK 5

#define MASTER 0
#define SLAVE 1

#define  outCS() DDRC |= (1<<CS)
#define  lowCS() PORTC &= ~(1<<CS)
#define  highCS() PORTC |= (1<<CS)

/*
Инициализация SPI.
*/
void initSPI(uint8_t mode);

/*
Отправка данных. 
cData - данные для передачи по SPI.
*/
void sendSPI(uint8_t cData);

/*
Прием данных. 
return - данные пришедние по SPI.
*/
uint8_t getSPI();

#endif

Added src/Communication_Atmega8_Studio5/Communication_Atmega8_Studio5/src/UART.c.

































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
Студенческий клуб разработчиков компьютерных систем 
			Проект "Mr.General"

Модуль предназначен для обмена данными по UART.

Программа написана для микроконтроллера AVR ATmega 16.
Тактовая частота процессора - 8 МГц.

Для компиляции использовались инструменты Atmel AVR Studio 5
(Version 5.1.208).

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <avr/interrupt.h>
#include <avr/io.h>
#include <stdint.h>
#include <stdio.h>
#include "UART.h"

#define F_CPU 8000000 
// Скорость обмена
#define BAUDRATE 9600
#define BAUDDIVIDER F_CPU/16/BAUDRATE-1


#define SIZE_MESSEGE 30
#define SIZE_BUFRX 2
#define SIZE_BUFTX 20

void addStrTransmit(char *add_str);
char* takeStrTransmit();


static char buffer_RX[SIZE_BUFRX][SIZE_MESSEGE];
static uint8_t busy_str_RX = 0;
static uint8_t empty_str_RX = 0;

static char *ptr_TX = NULL;
static char *buffer_TX[SIZE_BUFTX] = {NULL};
static uint8_t empty_TX = 0;
static uint8_t take_TX = 0;

static uint8_t busyUART = 0;
static uint8_t transmiting = 0;


// Добавление строки в буффер для передачи
void addStrTransmit(char *add_str)
{
	buffer_TX[empty_TX++] = add_str;
	if (empty_TX >= SIZE_BUFTX){
		empty_TX = 0;
	}	
	/*if (empty_TX == take_TX)
		ptr_TX = "ERROR SIZE_BUFTX UART";*/
}

// Взятие строки из буффера для передачи
char* takeStrTransmit()
{ 
	if(take_TX >= SIZE_BUFTX){
		take_TX = 0; 
	}	
	if(take_TX == empty_TX){
		return NULL;
	}	
	return buffer_TX[take_TX++];
}

// Поставка строки в очередь для передачи данных, запуск передачи
void sendStrUART (char *str_send)
{
	if (str_send != NULL){
		if (!transmiting){
			ptr_TX = str_send;
			transmiting = 1;
		} else
			addStrTransmit(str_send);
	}
}

void sendingStrUART(char *str_send)
{
	while(transmiting)
		processTransmitUART();
	ptr_TX = str_send;
	transmiting = 1;
	while(transmiting)
		processTransmitUART();
}

// Управление процессом передачи данных
void processTransmitUART()
{ 
	if((transmiting) && (!busyUART)){
		if (*ptr_TX == '\0'){
			busyUART = 1;
			UDR = '\r';
			ptr_TX = takeStrTransmit();
			if(ptr_TX == NULL){
				transmiting = 0;
			}	
		} else {
			busyUART = 1;
			UDR = *ptr_TX++;
		}
	}	
}

// Управление процессом приема данных
void processReceiveUART ()
{
	static uint8_t empty_char_RX = 0;
	buffer_RX[empty_str_RX][empty_char_RX] = UDR; 	
	if (buffer_RX[empty_str_RX][empty_char_RX] == '\r'){
		buffer_RX[empty_str_RX][empty_char_RX] = '\0';
		if (++empty_str_RX >= SIZE_BUFRX){
			empty_str_RX = 0;
		}	
		/*if (empty_str_RX >= busy_str_RX)
			sendStrUART("ERROR SIZE_BUFRX UART");*/
		empty_char_RX = 0;
		busyUART = 0;
	} 
	else {
		if(++empty_char_RX >= SIZE_MESSEGE){
				empty_char_RX = 0;
				sendStrUART("ERROR SIZE_MESSEGE UART");
		}
		busyUART = 1;
	}
}

char *getStrUART ()
{	
	if(busy_str_RX >= SIZE_BUFRX){
		busy_str_RX = 0; 
	}	
	if(busy_str_RX == empty_str_RX){
		return NULL;
	}	
	return buffer_RX[busy_str_RX++];
}

// Прирывание вызваное приходом данных 
ISR(USART_RXC_vect)
{	
	processReceiveUART ();
}

// Прирывание вызваное отправкой данных 
ISR(USART_TXC_vect)
{	
	busyUART = 0;
}	

void initUART()
{
	// Установка BAUDRATE
	UBRRH = (uint8_t)((BAUDDIVIDER) >> 8);
	UBRRL = (uint8_t)(BAUDDIVIDER);
	// Запуск приемника и передатчика, разрешение прерываний
	// после приема 
	UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE)| (1 << TXCIE) ;
	// Установка формата: 8 бит + 1 стопбит
	UCSRC = (1 << URSEL )| (1 << UCSZ0) | (1 << UCSZ1);
}



Added src/Communication_Atmega8_Studio5/Communication_Atmega8_Studio5/src/UART.h.

































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
	Студенческий клуб разработчиков компьютерных систем 
				Проект "Mr.General"

Это заголовочный файл к файлу UART.c

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdint.h>

#ifndef UART_TX_RX_H
#define UART_TX_RX_H

#define NUMBER_BATES_RX 1
#define NUMBER_BATES_TX 1


/*
Инициализация UART.
*/
void initUART();

/*
Отправка данных. 
str - указатель на строку для отправки по UART.
*/
void sendStrUART (char *str);

/*
Прием данных. 
return - указатель на строку пришедшую по UART.
*/
char* getStrUART ();

// Управление процессом передачи данных
void processTransmitUART();

// Управление процессом приема данных
void processReceiveUART ();

void sendingStrUART(char *str_send);

#endif

Added src/firebot/RoboCar.atsln.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Microsoft Visual Studio Solution File, Format Version 11.00
# Atmel Studio Solution File, Format Version 11.00
Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "RoboCar", "RoboCar\RoboCar.cproj", "{5D7DC3DF-BEAE-4577-83C6-75B3C0F4FAE0}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|AVR = Debug|AVR
		Release|AVR = Release|AVR
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{5D7DC3DF-BEAE-4577-83C6-75B3C0F4FAE0}.Debug|AVR.ActiveCfg = Debug|AVR
		{5D7DC3DF-BEAE-4577-83C6-75B3C0F4FAE0}.Debug|AVR.Build.0 = Debug|AVR
		{5D7DC3DF-BEAE-4577-83C6-75B3C0F4FAE0}.Release|AVR.ActiveCfg = Release|AVR
		{5D7DC3DF-BEAE-4577-83C6-75B3C0F4FAE0}.Release|AVR.Build.0 = Release|AVR
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
EndGlobal

Added src/firebot/RoboCar.atsuo.

cannot compute difference between binary files

Added src/firebot/RoboCar/RoboCar.c.



































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
 * RoboCar.c
 *
 * Created: 12.05.2015 17:42:26
 *  Author: Администратор
 */ 

#include "src/RobotControl.h"


int main(void)
{
    while(1)
    {
		mainRobot();
    }
}

Added src/firebot/RoboCar/RoboCar.cproj.













































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectVersion>6.2</ProjectVersion>
    <ToolchainName>com.Atmel.AVRGCC8.C</ToolchainName>
    <ProjectGuid>{5d7dc3df-beae-4577-83c6-75b3c0f4fae0}</ProjectGuid>
    <avrdevice>ATmega16</avrdevice>
    <avrdeviceseries>none</avrdeviceseries>
    <OutputType>Executable</OutputType>
    <Language>C</Language>
    <OutputFileName>$(MSBuildProjectName)</OutputFileName>
    <OutputFileExtension>.elf</OutputFileExtension>
    <OutputDirectory>$(MSBuildProjectDirectory)\$(Configuration)</OutputDirectory>
    <AssemblyName>RoboCar</AssemblyName>
    <Name>RoboCar</Name>
    <RootNamespace>RoboCar</RootNamespace>
    <ToolchainFlavour>Native</ToolchainFlavour>
    <KeepTimersRunning>true</KeepTimersRunning>
    <OverrideVtor>false</OverrideVtor>
    <CacheFlash>true</CacheFlash>
    <ProgFlashFromRam>true</ProgFlashFromRam>
    <RamSnippetAddress>0x20000000</RamSnippetAddress>
    <UncachedRange />
    <preserveEEPROM>true</preserveEEPROM>
    <OverrideVtorValue>exception_table</OverrideVtorValue>
    <BootSegment>2</BootSegment>
    <eraseonlaunchrule>0</eraseonlaunchrule>
    <AsfFrameworkConfig>
      <framework-data xmlns="">
        <options />
        <configurations />
        <files />
        <documentation help="" />
        <offline-documentation help="" />
        <dependencies>
          <content-extension eid="atmel.asf" uuidref="Atmel.ASF" version="3.21.0" />
        </dependencies>
      </framework-data>
    </AsfFrameworkConfig>
    <avrtool>com.atmel.avrdbg.tool.simulator</avrtool>
    <com_atmel_avrdbg_tool_simulator>
      <ToolOptions xmlns="">
        <InterfaceProperties>
        </InterfaceProperties>
      </ToolOptions>
      <ToolType xmlns="">com.atmel.avrdbg.tool.simulator</ToolType>
      <ToolNumber xmlns="">
      </ToolNumber>
      <ToolName xmlns="">Simulator</ToolName>
    </com_atmel_avrdbg_tool_simulator>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
    <ToolchainSettings>
      <AvrGcc>
        <avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
        <avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
        <avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
        <avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
        <avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
        <avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
        <avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
        <avrgcc.compiler.symbols.DefSymbols>
          <ListValues>
            <Value>NDEBUG</Value>
          </ListValues>
        </avrgcc.compiler.symbols.DefSymbols>
        <avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level>
        <avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
        <avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
        <avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
        <avrgcc.linker.libraries.Libraries>
          <ListValues>
            <Value>libm</Value>
          </ListValues>
        </avrgcc.linker.libraries.Libraries>
        <avrgcc.linker.libraries.LibrarySearchPaths>
          <ListValues>
            <Value>D:\Work\Mr.General\svn\src</Value>
          </ListValues>
        </avrgcc.linker.libraries.LibrarySearchPaths>
      </AvrGcc>
    </ToolchainSettings>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
    <ToolchainSettings>
      <AvrGcc>
        <avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
        <avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
        <avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
        <avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
        <avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
        <avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
        <avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
        <avrgcc.compiler.symbols.DefSymbols>
          <ListValues>
            <Value>DEBUG</Value>
          </ListValues>
        </avrgcc.compiler.symbols.DefSymbols>
        <avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
        <avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
        <avrgcc.compiler.optimization.DebugLevel>Default (-g2)</avrgcc.compiler.optimization.DebugLevel>
        <avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
        <avrgcc.linker.libraries.Libraries>
          <ListValues>
            <Value>libm</Value>
          </ListValues>
        </avrgcc.linker.libraries.Libraries>
        <avrgcc.linker.libraries.LibrarySearchPaths>
          <ListValues>
            <Value>D:\Work\Mr.General\svn\src</Value>
          </ListValues>
        </avrgcc.linker.libraries.LibrarySearchPaths>
        <avrgcc.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcc.assembler.debugging.DebugLevel>
      </AvrGcc>
    </ToolchainSettings>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="RoboCar.c">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Communication subsystem\RFM.c">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Communication subsystem\RFM.h">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Communication subsystem\SPI.c">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Communication subsystem\SPI.h">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Movement subsystem\MovementAgent.c">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Movement subsystem\MovementAgent.h">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Movement subsystem\TimerMove.c">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Movement subsystem\TimerMove.h">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Movement subsystem\WheelDrive.c">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Movement subsystem\WheelDrive.h">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\RobotControl.c">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\RobotControl.h">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Scanning subsystem\ADC.c">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Scanning subsystem\ADC.h">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Scanning subsystem\CollisionAgent.c">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Scanning subsystem\CollisionAgent.h">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Scanning subsystem\LED.c">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Scanning subsystem\LED.h">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Scanning subsystem\ScanAgent.c">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Scanning subsystem\ScanAgent.h">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Scanning subsystem\ScanDrives.c">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Scanning subsystem\ScanDrives.h">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Scanning subsystem\TimerScan.c">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Scanning subsystem\TimerScan.h">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Scanning subsystem\UART.c">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Scanning subsystem\UART.h">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Scanning subsystem\ULTRASONIC.c">
      <SubType>compile</SubType>
    </Compile>
    <Compile Include="src\Scanning subsystem\ULTRASONIC.h">
      <SubType>compile</SubType>
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <Folder Include="src\" />
    <Folder Include="src\Communication subsystem\" />
    <Folder Include="src\Movement subsystem\" />
    <Folder Include="src\Scanning subsystem\" />
  </ItemGroup>
  <Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
</Project>

Added src/firebot/RoboCar/src/Communication subsystem/RFM.c.































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
Студенческий клуб разработчиков компьютерных систем 
			Проект "Mr.General"

Модуль предназначен для обмена данными по RFM.

Программа написана для микроконтроллера AVR ATmega 16.
Тактовая частота процессора - 8 МГц.

Для компиляции использовались инструменты Atmel AVR Studio 5
(Version 5.1.208).

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdint.h>
#include <stdio.h>
#include <avr/io.h>
#include "SPI.h"
#include "RFM.h"


#define SIZE_MESSEGE 30
#define SIZE_BUFRX 2
#define SIZE_BUFTX 5

void sendByteRFM(uint8_t out_data);
uint8_t getByteRFM();
uint8_t isTransmitRFM();
uint8_t isReceiveRFM();
uint8_t processTransmitRFM();
uint8_t processReceiveRFM();
void addTransmitRFM(char *add_str);
char* takeTransmitRFM();

static char *pointerTX_RFM = NULL;
static char *buffer_TX_RFM[SIZE_BUFTX] = {NULL};
static uint8_t empty_TX_RFM = 0;
static uint8_t take_TX_RFM = 0;

static char bufferRX_RFM[SIZE_BUFRX][SIZE_MESSEGE];
static uint8_t busy_str_RX_RFM = 0;	
static uint8_t empty_str_RX_RFM = 0;

uint8_t transmitingRFM = 0;
uint8_t receivingRFM = 0;


void addTransmitRFM(char *add_str)
{
	buffer_TX_RFM[empty_TX_RFM++] = add_str;
	if (empty_TX_RFM >= SIZE_BUFTX){
		empty_TX_RFM = 0;
	}	
}


// Взятие строки из буффера для передачи
char* takeTransmitRFM()
{ 
	if(take_TX_RFM >= SIZE_BUFTX){
		take_TX_RFM = 0; 
	}	
	if(take_TX_RFM == empty_TX_RFM){
		return NULL;
	}	
	return  buffer_TX_RFM[take_TX_RFM++];
}

void sendStrRFM (char *str)
{
	if(str != NULL){
		if(!receivingRFM){
			if(!transmitingRFM){
				setModeRFM(TRANSMIT);
				pointerTX_RFM = str;
				sendByteRFM(*pointerTX_RFM);
				pointerTX_RFM++;
				transmitingRFM = 1;
			}
			else{
				addTransmitRFM(str);
			}
		}	
	}
}

void sendingStrRFM (char *str)
{
	if(str != NULL){
		setModeRFM(TRANSMIT);
		pointerTX_RFM = str;
		sendByteRFM(*pointerTX_RFM);
		pointerTX_RFM++;
		transmitingRFM = 1;
		while(processTransmitRFM() == 1);
	}
}

void sendByteRFM(uint8_t out_data)
{
	PORTB &= ~(1<<SS);
	sendSPI(W_TX_PAYLOAD);
	sendSPI(out_data);	
	PORTB |= (1<<SS);	
}
					
uint8_t processRFM()
{
	static uint8_t link_RFM = 1;
	if(transmitingRFM){
		if(processTransmitRFM())
			link_RFM = 1;
		else
			link_RFM = 0;
	}
	else {
		if(processReceiveRFM())
			link_RFM = 1;
	}
	return link_RFM;
}

// Управление процессом передачи данных
uint8_t processTransmitRFM()
{
	if(isTransmitRFM()){
		sendByteRFM(*pointerTX_RFM);
		if (*pointerTX_RFM == '\0'){
			pointerTX_RFM = takeTransmitRFM();
			if(pointerTX_RFM == NULL){
				while(!isTransmitRFM());	
				setModeRFM(RECEIVE);
				transmitingRFM = 0;
				return 3;
			}
		} 
		else {
			pointerTX_RFM++;
		}	
	}
	else{
		if (getStatusReg() & (1<<MAX_RT_BIT)){
			sendCommandRFM ((W_REGISTER_CMD | STATUS_REG), (1<<MAX_RT_BIT));
			setModeRFM(RECEIVE);
			transmitingRFM = 0;
			return 0;
		}
	}
	return 1;
}


uint8_t processReceiveRFM()
{
	if(isReceiveRFM()){
		static uint8_t empty_char_RX = 0;
		bufferRX_RFM[empty_str_RX_RFM][empty_char_RX] = getByteRFM();	
		if (bufferRX_RFM[empty_str_RX_RFM][empty_char_RX] == '\0'){
			receivingRFM = 0;
			empty_char_RX = 0;
			if (++empty_str_RX_RFM >= SIZE_BUFRX){
				empty_str_RX_RFM = 0;
			}	
		}
		else {
			++empty_char_RX;
			receivingRFM = 1;
		}
		return 1;
	}
	return 0;
}

char *getStrRFM ()
{	
	if(busy_str_RX_RFM >= SIZE_BUFRX){
		busy_str_RX_RFM = 0; 
	}	
	if(busy_str_RX_RFM == empty_str_RX_RFM){
		return NULL;
	}	
	return bufferRX_RFM[busy_str_RX_RFM++];
}	

uint8_t isTransmitRFM()
{	
	if (getStatusReg() & (1<<TX_DS_BIT)){
		sendCommandRFM ((W_REGISTER_CMD | STATUS_REG), (1<<TX_DS_BIT));
		return 1;
	}
	return 0;		
}

uint8_t isReceiveRFM()
{
	//if ((PINB &(1<<IRQ)) == 0){
	if (getStatusReg() & (1<<RX_DR_BIT)){	
		// Очищяем флаг прерывания при приеме сообщения в RFM
		sendCommandRFM ((W_REGISTER_CMD | STATUS_REG), (1<<RX_DR_BIT));
		return 1;
	}
	else return 0;
}

void sendCommandRFM(uint8_t first_comand, uint8_t second_comand)
{
	PORTB &= ~(1<<SS);
	sendSPI(first_comand);
	sendSPI(second_comand);
	PORTB |= (1<<SS);
}


uint8_t getStatusReg()
{
	uint8_t status = 0;
	PORTB &= ~(1<<SS);
	sendSPI(0xFF);
	status = getSPI();
	PORTB |= (1<<SS);
	return status;	
}

uint8_t getByteRFM()
{
	uint8_t data = 0;
	PORTB &= ~(1<<SS);
	// Отправляем команду получить данные RFM
	sendSPI(R_RX_PAYLOAD);
	sendSPI(0xFF);
	data = getSPI();
	PORTB |= (1<<SS);
	return 	data;
}	
///////////

void initRFM(uint8_t modeRFM)
{
	switch (modeRFM)
	{
		case RECEIVE:
					DDRB &= ~(1<<CE);
					// Устанавливаем количество байт приема
					sendCommandRFM((W_REGISTER_CMD | RX_PW_P0_REG), 0x1);	
					// Включаем питание настраеваем на приемник (reciever)
					sendCommandRFM((W_REGISTER_CMD | CONFIG_REG),((1<<EN_CRC_BIT)|(1<<PWR_UP_BIT)|(1<<PRIM_RX_BIT)));
					PORTB |= (1<<CE);
					break;
		case TRANSMIT:
					DDRB |= (1<<CE);
					// Включаем питание настраеваем на передатчик (transmiter)
					sendCommandRFM((W_REGISTER_CMD | CONFIG_REG),((1<<EN_CRC_BIT) | (1<<PWR_UP_BIT)));
					PORTB |= (1<<CE);
					break;
	}	
}	


void setModeRFM(uint8_t modeRFM)
{
	switch (modeRFM)
	{
		case RECEIVE:
					PORTB &= ~(1<<CE);
					sendCommandRFM((W_REGISTER_CMD | CONFIG_REG),(0<<PWR_UP_BIT));
					sendCommandRFM((W_REGISTER_CMD | RX_PW_P0_REG), 0x1);	
					// Включаем питание настраеваем на приемник (reciever)
					sendCommandRFM((W_REGISTER_CMD | CONFIG_REG),((1<<EN_CRC_BIT)|(1<<PWR_UP_BIT)|(1<<PRIM_RX_BIT)));
					PORTB |= (1<<CE);
					break;
		case TRANSMIT:
					PORTB &= ~(1<<CE);
					sendCommandRFM((W_REGISTER_CMD | CONFIG_REG),(0<<PWR_UP_BIT));
					// Включаем питание настраеваем на передатчик (transmiter)
					sendCommandRFM((W_REGISTER_CMD | CONFIG_REG),((1<<EN_CRC_BIT)|(1<<PWR_UP_BIT)|(0<<PRIM_RX_BIT)));
					PORTB |= (1<<CE);
					break;
	}
}



Added src/firebot/RoboCar/src/Communication subsystem/RFM.h.





































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
	Студенческий клуб разработчиков компьютерных систем 
				Проект "Mr.General"

Это заголовочный файл к файлу RFM.c

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdint.h>
#ifndef RFM_H
#define RFM_H


#define IRQ 0
#define CE 1

#define RECEIVE 0
#define TRANSMIT 1

#define FLUSH_RX 0xE2
#define FLUSH_TX 0xE1
#define W_TX_PAYLOAD_NOACK 0xB0
#define W_REGISTER_CMD 0x20
#define R_REGISTER_CMD 0

#define RX_PW_P0_REG 0x11

#define CONFIG_REG 0x0
#define PRIM_RX_BIT 0
#define PWR_UP_BIT 1
#define EN_CRC_BIT 3

#define STATUS_REG 0x7
#define RX_DR_BIT 6
#define TX_DS_BIT 5 
#define MAX_RT_BIT 4

#define R_RX_PAYLOAD 0x61
#define W_TX_PAYLOAD 0xA0

/*
Инициализация RFM.
modeRFM - режим.
*/
void initRFM(uint8_t modeRFM);

/*
Выбор режима RFM.
modeRFM - режим.
*/
void setModeRFM(uint8_t modeRFM);

/*
Отправка данных. 
str - указатель на строку для отправки по RFM.
*/
void sendStrRFM (char *str);

/*
Прием данных. 
return - указатель на строку пришедшую по RFM.
*/
char *getStrRFM ();

// Управление процессом обмена данными
uint8_t processRFM();

//Отправка команд RFM.
void sendCommandRFM(uint8_t first_comand, uint8_t second_comand);

//Получение статусного регистра RFM.
uint8_t getStatusReg();

void sendingStrRFM (char *str);


#endif

Added src/firebot/RoboCar/src/Communication subsystem/SPI.c.



































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
Студенческий клуб разработчиков компьютерных систем 
			Проект "Mr.General"

Модуль предназначен для обмена данными по SPI.

Программа написана для микроконтроллера AVR ATmega 16.
Тактовая частота процессора - 8 МГц.

Для компиляции использовались инструменты Atmel AVR Studio 5
(Version 5.1.208).

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdint.h>
#include <avr/io.h>
#include "SPI.h"

//Инициализация SPI
void initSPI(uint8_t mode)
{
	switch (mode)
	{
		
		case MASTER:
					/* Set MOSI, SCK, SS output, all others input */
					DDRB |= 1<<MOSI | 1<<SCK | 1<<SS;
					//setPin (B,SS);
					PORTB &= ~(1<<SS);
					/*Инициализация SPI в регистре SPCR (SPI CONTROL REGISTER) на ведущего (Master), разрешение работы SPI */
					SPCR = (1<<SPE)|(1<<MSTR);
					break;
		case SLAVE:
					/* Set MISO output, all others input */
					DDRB |= 1<<6 | 1<<4;
					//Инициализация SPI в регистре SPCR (SPI CONTROL REGISTER) на ведомого (Slave)
					SPCR = (1<<SPE);
					break;			
	}
}

//Отправка данных
void sendSPI(uint8_t cData)
{
	// Start transmission 
	SPDR = cData;
	// Wait for transmission complete 
	while(!(SPSR & (1<<SPIF)));
}

//Прием данных
uint8_t getSPI()
{
	while(!(SPSR & (1<<SPIF)));
	//Return data register 
	return SPDR;
}	



Added src/firebot/RoboCar/src/Communication subsystem/SPI.h.

























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
	Студенческий клуб разработчиков компьютерных систем 
				Проект "Mr.General"

Это заголовочный файл к файлу SPI.c

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdint.h>
#ifndef SPI_H 
#define SPI_H

#define SS 4
#define MOSI 5
#define SCK 7

#define MASTER 0
#define SLAVE 1

/*
Инициализация SPI.
mode - выбор режима SPI (ведущий или ведомый).
*/
void initSPI(uint8_t mode);

/*
Отправка данных. 
cData - данные для передачи по SPI.
*/
void sendSPI(uint8_t cData);

/*
Прием данных. 
return - данные пришедние по SPI.
*/
uint8_t getSPI();

#endif

Added src/firebot/RoboCar/src/Movement subsystem/MovementAgent.c.



































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
Студенческий клуб разработчиков компьютерных систем 
			Проект "Mr.General"

Модуль предназначен для управления перемещением робота.

Программа написана для микроконтроллера AVR ATmega 16.
Тактовая частота процессора - 8 МГц.

Для компиляции использовались инструменты Atmel AVR Studio 5
(Version 5.1.208).

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <avr/io.h>
#include <stdint.h>
#include <util/atomic.h>
#include "MovementAgent.h"
#include "WheelDrive.h"
#include "TimerMove.h"


#define TIME_TIMER_INERRUPT 0.000255
#define VELOCITY_MAX (11.461246875*1.03)
#define VELOCITY_MIN (4.0938333333*1.05)
#define VELOCITY_TURNED_MAX (112.5*1.1) 
#define VELOCITY_TURNED_MIN (44*0.8888)
#define TRAVEL_MAX (VELOCITY_MAX*TIME_TIMER_INERRUPT)
#define TRAVEL_MIN (VELOCITY_MIN*TIME_TIMER_INERRUPT)
#define TURNED_MAX (VELOCITY_TURNED_MAX*TIME_TIMER_INERRUPT)
#define TURNED_MIN (VELOCITY_TURNED_MIN*TIME_TIMER_INERRUPT)

/*
Задание движения робота, его остановка и изменение скорости.
direction - направление движения;
speed - скорость движения; 
*/
void move(DirectRobot_t direction, Speed_t speed);
uint8_t is_limit;

//Перемещение робота на заданную дистанцию с заданной скоростью и направлением
uint8_t movement(DirectRobot_t direction, Speed_t speed, uint8_t limit)
{
	uint32_t time_move = 0;
	if (limit > 0){
		//Расчет количества прерываний таймера при заданной скорости
		ATOMIC_BLOCK (ATOMIC_RESTORESTATE){
			
			if ((direction == FORWARD) || (direction == BACKWARD)){
				if (speed == MAX){
						time_move = limit / TRAVEL_MAX;		
				} else{
						time_move = limit / TRAVEL_MIN;
					}	
			} 
			
			else{
				if (speed == MAX){
						time_move = limit / TURNED_MAX;  
				} else{
						time_move = limit / TURNED_MIN;
				}
			}	
		}	
		is_limit = 1;
		startCtrMove(time_move);
	} 
	else is_limit = 0;
	move(direction,speed);
	return 1;
}

void stop()
{
	move(STOP,1);
}

//Управление процессом перемещения.  
uint8_t processMovement()
{
	if (is_limit){
		if (completeCtrMove()){
			return 1;
		}
	}
	return 0;
}

void move(DirectRobot_t direction, Speed_t speed)
{
	/*const uint8_t MIN_LEFT = 140;
	const uint8_t MIN_RIGHT = 152;*/
	const uint8_t MIN_LEFT = 188;
	const uint8_t MIN_RIGHT = 180;
	const uint8_t MAX_LEFT = 255;
	const uint8_t MAX_RIGHT = 255;
	switch (direction)
	{
		case STOP:
			rotationWheel(0,0,0);
			rotationWheel(1,0,0);
			break;	
		case FORWARD:
			if (speed == MIN){
				rotationWheel(0,FORWARD,MIN_LEFT);
				rotationWheel(1,FORWARD,MIN_RIGHT);
			}else{
				rotationWheel(0,FORWARD,MAX_LEFT);
				rotationWheel(1,FORWARD,MAX_RIGHT);
			}
			break;
		case BACKWARD:
			if (speed == MIN){
				rotationWheel(0,BACKWARD,MIN_LEFT);
				rotationWheel(1,BACKWARD,MIN_RIGHT);
			}else{
				rotationWheel(0,BACKWARD,MAX_LEFT);
				rotationWheel(1,BACKWARD,MAX_RIGHT);
			}
			break;
		case LEFT:
			if (speed == MIN){
				rotationWheel(0,BACKWARD,MIN_LEFT);
				rotationWheel(1,FORWARD,MIN_RIGHT);
			}else{
				rotationWheel(0,BACKWARD,MAX_LEFT);
				rotationWheel(1,FORWARD,MAX_RIGHT);
			}
			break;
		case RIGHT:
			if (speed == MIN){
				rotationWheel(0,FORWARD,MIN_LEFT);
				rotationWheel(1,BACKWARD,MIN_RIGHT);
			}else{
				rotationWheel(0,1,MAX_LEFT);
				rotationWheel(1,2,MAX_RIGHT);
			}
			break;						
	}
}

Added src/firebot/RoboCar/src/Movement subsystem/MovementAgent.h.



















































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
	Студенческий клуб разработчиков компьютерных систем 
				Проект "Mr.General"

Это заголовочный файл к файлу MovementAgent.c

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdint.h>

#ifndef MOVE_AGENT_H
#define MOVE_AGENT_H

#define MOVEMENT_COMPLETE 1
typedef enum{STOP, FORWARD, BACKWARD, LEFT, RIGHT}DirectRobot_t;
typedef enum{MIN = 1, MAX}Speed_t;


/*
Перемещение робота на заданную дистанцию с заданной скоростью и направлением.
direction - направление движения;
speed - скорость движения;
limit - ограничение перемещения.
*/
uint8_t movement(DirectRobot_t direction, Speed_t speed, uint8_t limit);

//Управление процессом перемещения. 
//return - cостояние перемещения, 1 - робот перемещяеться, 0 - робот остановился.  
uint8_t processMovement();

//Возврат текущего направления движения робота
DirectRobot_t getDirectionMove();

void stop();

#endif

Added src/firebot/RoboCar/src/Movement subsystem/TimerMove.c.

























































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
Студенческий клуб разработчиков компьютерных систем 
			Проект "Mr.General"

Модуль предназначен для управления счетчиком перемещения.

Программа написана для микроконтроллера AVR ATmega 16.
Тактовая частота процессора - 8 МГц.

Для компиляции использовались инструменты Atmel AVR Studio 5
(Version 5.1.208).

Используемые ресурсы микроконтроллера:
* Таймера общего назначения TIM1;
* Прерывание TIMER0_OVF_vect;

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <avr/interrupt.h>
#include <stdint.h>
#include <util/atomic.h>
#include "TimerMove.h"


uint16_t ctr_move;
uint8_t complete_ctr_move;

//Запуск счетчика
void startCtrMove(uint16_t value)
{
	ATOMIC_BLOCK (ATOMIC_RESTORESTATE){
		ctr_move= value;
	}
	complete_ctr_move = 0;
	//Запуск прерывания по переполнению TIM0
	TIMSK |= (1<<TOIE0);
}

//Возврат окончания счета
uint8_t completeCtrMove()
{
	return complete_ctr_move;
}

//Вектор прерываний по переполнению TIM1
ISR(TIMER0_OVF_vect)
{
	if(--ctr_move == 0){
		complete_ctr_move = 1;
		//Остключение прерываний по переполнению TIM0
		TIMSK &= ~(1<<TOIE0);
	}
}


Added src/firebot/RoboCar/src/Movement subsystem/TimerMove.h.





































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
	Студенческий клуб разработчиков компьютерных систем 
				Проект "Mr.General"

Это заголовочный файл к файлу TIMER.c

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdint.h>


#ifndef TIMER_H
#define TIMER_H

/*
Запуск счетчика.
value - значение счетчика.
*/
void startCtrMove(uint16_t value);

/*
Возврат состояния счета.
return - 0 - счет не завершен, 1- счет завершен.
*/
uint8_t completeCtrMove();



#endif

Added src/firebot/RoboCar/src/Movement subsystem/Timers.c.































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
Студенческий клуб разработчиков компьютерных систем 
			Проект "Mr.General"

Модуль предназначен для управления счетчиками.

Программа написана для микроконтроллера AVR ATmega 16.
Тактовая частота процессора - 8 МГц.

Для компиляции использовались инструменты Atmel AVR Studio 5
(Version 5.1.208).

Используемые ресурсы микроконтроллера:
* Таймера общего назначения TIM1;
* Прерывание TIMER0_OVF_vect;

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <avr/interrupt.h>
#include <stdint.h>
#include <util/atomic.h>
#include "Timers.h"


static uint16_t ctr[2];
static uint8_t complete_ctr[2];

//Запуск счетчика
void startCounter(uint8_t chose_ctr, uint16_t value)
{
	ATOMIC_BLOCK (ATOMIC_RESTORESTATE){
		ctr[chose_ctr] = value;
	}
	complete_ctr[chose_ctr] = 0;
	switch(chose_ctr){
		case 0:
			//Запуск прерывания по переполнению TIM0
			TIMSK |= (1<<TOIE0);
			break;
		case 1:
			//Прерываниe по переполнению TIM1
			TIMSK |= (1<<TOIE1);
			break;	
	}
}

//Возврат окончания счета
uint8_t completeCounter(uint8_t chose_ctr)
{
	return complete_ctr[chose_ctr];
}

//Вектор прерываний по переполнению TIM1
ISR(TIMER0_OVF_vect)
{
	if(--ctr[0] == 0){
		complete_ctr[0] = 1;
		//Остключение прерываний по переполнению TIM0
		TIMSK &= ~(1<<TOIE0);
	}
}

//Вектор прерывания по переполнению TIM1
ISR(TIMER1_OVF_vect)
{
	if(--ctr[1] == 0){
		complete_ctr[1] = 1;
		// Отключение прерываниe по переполнению TIM1
		TIMSK &= ~(1<<TOIE1);
	}
}



Added src/firebot/RoboCar/src/Movement subsystem/Timers.h.









































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
	Студенческий клуб разработчиков компьютерных систем 
				Проект "Mr.General"

Это заголовочный файл к файлу TIMER.c

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdint.h>


#ifndef TIMER_H
#define TIMER_H

/*
Запуск счетчика.
chose_ctr - выбор счетчика;
value - значение счетчика.
*/
void startCounter(uint8_t chose_ctr, uint16_t value);

/*
Возврат окончания счета.
chose_ctr - выбор счетчика.
return - значение счетчика.
*/
uint8_t completeCounter(uint8_t chose_ctr);



#endif

Added src/firebot/RoboCar/src/Movement subsystem/WheelDrive.c.













































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
Студенческий клуб разработчиков компьютерных систем 
			Проект "Mr.General"

Модуль предназначен для управдения ДПТ.

Программа написана для микроконтроллера AVR ATmega 16.
Тактовая частота процессора - 8 МГц.

Назначение выводов: PD7 - левое(взгляд спереди) колесо вперед (1A) , PC0 - левое колесо реверс (2A);
										PB3 - правое колесо вперед (3A), PB2 - правое колесо реверс (4A);

Для компиляции использовались инструменты Atmel AVR Studio 5
(Version 5.1.208).

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <avr/interrupt.h>
#include <stdint.h>
#include <avr/io.h>
#include "WheelDrive.h"


#define LEFT 0
#define RIGHT 1

#define STOP 0
#define FORWARD 1
#define BACKWARD 2


void initWheelDrive ()
{
	// инициализируем таймер 0 и 2 и настраеваем их на ШИМ
	//WGM00,WGMx1 - настраиваем быстрый шим
	//COMx1 - cброс при совпадении 
	//CS - приделитель
	//Пределитель 8
	TCCR0 |= 1<<WGM00 | 1<<WGM01 | 1<<COM01 | 1<<CS01;
	//Пределитель 1
	TCCR2 |= 1<<WGM20 | 1<<WGM21 | 1<<COM21 | 1<<CS20;
	//outPin(B,3);
	DDRB |= (1<<3);
	//outPin(B,2);
	DDRB |= (1<<2);
	//outPin(C,0);
	DDRC |= (1<<0);
	//outPin(D,7);
	DDRD |= (1<<7);
}


//Задание направления вращение двигателей.	
void rotationWheel (uint8_t wheel, uint8_t direction_rotation, uint8_t speed_rotation)
{
	switch (wheel)
	{
		case LEFT:	
			switch (direction_rotation)
			{
				case FORWARD:
					PORTC &= ~(1<<0);
					OCR2 = speed_rotation;
					break;
				case BACKWARD:
					PORTC |= (1<<0);
					OCR2 = 255-speed_rotation;
					break;		
				case STOP:
					OCR2=0;
					PORTC &= ~(1<<0);
					break;						
			}
			break;	
		case RIGHT:	
			switch (direction_rotation)
			{
				case FORWARD:
					PORTB &= ~(1<<2);
					OCR0 = speed_rotation;
					break;				
				case BACKWARD:
					PORTB |= (1<<2);
					OCR0= 255-speed_rotation;
					break;		
				case STOP:
					OCR0=0;
					PORTB &= ~(1<<2);
					break;						
			}
			break;
	}					
}	




Added src/firebot/RoboCar/src/Movement subsystem/WheelDrive.h.































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
	Студенческий клуб разработчиков компьютерных систем 
				Проект "Mr.General"

Это заголовочный файл к файлу WheelDrive.c

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdint.h>
#ifndef WHEEL_DRIVE_H
#define Wheel_Drive_H

/*
Инициализация ШИМ и настройка портов, к которым подключаются двигатели на выход.
*/
void initWheelDrive();

/*
Задание направления вращение двигателей.	
wheel –  выбор двигателя, 0 – левый, 1 – правый;
direction – направление вращения и останов двигателя, 0 – стоп, 1 – вперед, 2 – реверс;
speed – скорость вращения двигателя, 1 - min до 255 - max.
*/
void rotationWheel (uint8_t wheel, uint8_t direction_rotation, uint8_t speed_rotation);

#endif

Added src/firebot/RoboCar/src/RobotControl.c.



























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
Студенческий клуб разработчиков компьютерных систем 
			Проект "Mr.General"

Модуль предназначен для управления обслуживания запросов 
клиента.

Программа написана для микроконтроллера AVR ATmega 16.
Тактовая частота процессора - 8 МГц.

Для компиляции использовались инструменты Atmel AVR Studio 5
(Version 5.1.208).

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <avr/interrupt.h>
#include "Communication subsystem/SPI.h"
#include "Communication subsystem/RFM.h"
#include "Scanning subsystem/ADC.h"
#include "Scanning subsystem/UART.h"
#include "Scanning subsystem/LED.h"
#include "Scanning subsystem/Ultrasonic.h"
#include "Scanning subsystem/ScanDrives.h"
#include "Scanning subsystem/ScanAgent.h"
#include "Scanning subsystem/CollisionAgent.h"
#include "Movement subsystem/WheelDrive.h"
#include "Movement subsystem/MovementAgent.h"
#include "RobotControl.h"

//Состояния конечного автомата
typedef enum{WAIT, MOVE, SCAN, MEASURE, AUTO}StatesRobot_t;

//Управление роботом
void processRobot();
/*
Установка состояния робота.
set_state - задание состояния.
*/
void setStateRobot(StatesRobot_t set_state);
/*
Обработка запроса клиента.
query - запрос клиента.
*/
void handlerQuery(char *query);
/*
Обработка запроса клиента на передвижение.
query_movement - запрос клиента;
return - статус опереции.
*/
uint8_t movementQuery(char *query_move);
/*
Обработка запроса клиента на сканирование.
query_scan - запрос клиента;
return - статус опереции.
*/
uint8_t scanQuery(char *query_scan);
/*
Обработка запроса клиента на измерение.
query_head - запрос клиента;
return - статус опереции.
*/
uint8_t measureQuery(char *query_measure);

void scanningCurrent();

char status_robot[10];					
StatesRobot_t state_robot = WAIT;

uint8_t state_autopilot;
float dist_left, dist_right;
uint8_t chose_way, turn_left;
uint8_t tmp1,tmp2;
uint8_t degree_turn = 1;

//Главная функция управления роботом
void mainRobot()
{	
	sei();
	initSPI(MASTER);	
	initRFM(TRANSMIT);	
	initUltrasonic();
	initDrive(HEAD);						
	initWheelDrive();							
	startADC(0);        // Запуск АЦП для его калибровки
	//sendStrRFM("Ready robot");
	setStateRobot(AUTO);
	
	/*LED(ON,LED_SCAN);
	LED(OFF,LED_RFM);
	//sprintf(status_robot,"Autopilot");
	onCheckCollision(FORWARD);
	state_autopilot = MOVE;
	movement(FORWARD,MIN,0);
	state_robot = AUTO;*/
	
    while(1)
	{
		processRobot();
		handlerQuery(getStrRFM());
		if (!processRFM())
			;//LED(ON,LED_RFM);
		//else
			//LED(OFF,LED_RFM);
		//processTransmitUART();
    }
}

//Управление роботом
void processRobot()
{
	static uint32_t i = 0, state_led = 0;
	static char* ptr_scan_result;
	static uint8_t state_tmp = 0;
	switch (state_robot){
		case WAIT:
			if (i++ > 10000)
			{
				switch (state_led){
					case 0:
						LED(ON,LED_SCAN);
						state_led = 1;
						break;
					case 1:
						LED(OFF,LED_SCAN);
						state_led = 0;
						break;
				}
				i = 0;
			}
			break;					
		case MOVE:
			if(processMovement()){
				setStateRobot(WAIT);
				sendStrRFM("Move complete");
			}
			/*if(isObstacleSurface()){
				setStateRobot(WAIT);
				sendStrRFM("Obstacle on SURFACE");
			}*/
			if(isObstacleSpace()){
				setStateRobot(WAIT);
				//sendStrRFM("obstacle");
				LED(ON,LED_RFM);
			}
			break;
		case SCAN:
			ptr_scan_result = getProcessScan();
			sendStrRFM(ptr_scan_result);
			if(ptr_scan_result == getEndingScan()){
				setStateRobot(WAIT);
			}
			break;
		case MEASURE:
			ptr_scan_result = getStrMeasure();
			if (ptr_scan_result != NULL){
				sendStrRFM(ptr_scan_result);
				setStateRobot(WAIT); 
			}
			break;
		case AUTO:
			switch(state_autopilot){
				//static uint8_t ctr_tmp = 0;
				case MOVE:
					if(isObstacleSpace()){
						stop();
						offCheckCollision();
						/*LED(ON,IR_ROBOT_3);
						LED(ON,IR_ROBOT_4);*/
						LED(ON,LED_RFM);
						LED(OFF,LED_SCAN);
						measure(ULTRASONIC, HEAD, HEAD_LEFT);
						state_autopilot = OBSTACLE_SPACE;
						chose_way = 0;
						ctr_tmp = 0;
						state_tmp = 0;
						//sendStrRFM("1");
					}
					else{
						//if(isObstacleSurface()){
						if(0){	
							stop();
							LED(ON,LED_RFM);
							LED(OFF,LED_SCAN);
							tmp1 = gettingADC(IR_ROBOT_1);
							tmp2 = gettingADC(IR_ROBOT_2); 
							offCheckCollision();
							if(tmp2 >= tmp1){
								turn_left = 1;
								LED(ON, IR_ROBOT_4);
							}
							else{
								LED(ON, IR_ROBOT_3);
								turn_left = 0;
							}
							movement(BACKWARD,MIN,5);	
							state_autopilot = OBSTACLE_SURFACE;
							chose_way = 0;
						}
					}
					break; 
				//Обнаружено припядствие
				case OBSTACLE_SPACE:
					
					switch(chose_way){
						case 0:
						switch (state_tmp)
						{
							case 0:
									if(readyDistance() || completeCtrScan()){
										dist_right = getUltrasonic();
										measure(ULTRASONIC, HEAD, HEAD_RIGHT);
										chose_way = 1;
										//sendStrRFM("2");
									}
									break;
								case 1:
									if (isMeasureUltrasonic()){
										dist_right = getUltrasonic();
										//sendStrRFM("2.1");
										chose_way = 1;
									}
									break;
							}
							//if(getStrMeasure() != NULL){
							/*else{
								if(readyDistance() == -1){
									LED(OFF, IR_ROBOT_4);
									movement(RIGHT, MIN, 25);
									setPositionDrive(HEAD, HEAD_LEFT);
									turn_left = 0;
									chose_way = 2;
								}
							}*/
							break;
						case 1:
							//if(getStrMeasure() != NULL){
							if (readyDistance()){
								//sendStrRFM("3");
								dist_left = getUltrasonic();
								if ((dist_left < 4) && (dist_right < 4)){
									movement(BACKWARD, MIN, 2);
									chose_way = 3;
								}
								else{
									if (dist_left >= dist_right){	
										LED(OFF, IR_ROBOT_4);
										movement(RIGHT, MIN, 30);
										setPositionDrive(HEAD, HEAD_LEFT);
										turn_left = 0;
										chose_way = 2;
									}
									else{
										LED(OFF, IR_ROBOT_3);
										movement(LEFT, MIN, 28);
										setPositionDrive(HEAD,HEAD_RIGHT);
										turn_left = 1;
										chose_way = 2;
									}	
								}
							}
							/*if (ctr_tmp++ > 1000){
								startUltrasonic();
							}*/
							
							/*else{
								if (readyDistance() == -1){
									LED(OFF, IR_ROBOT_4);
									movement(LEFT, MIN, 25);
									setPositionDrive(HEAD, HEAD_RIGHT);
									turn_left = 0;
									chose_way = 2;
								}
							}*/
							break;
						case 2:
							if(processMovement()){
								LED(OFF,LED_RFM);
								LED(ON,LED_SCAN);
								onCheckCollision(FORWARD_CHECK);
								movement(FORWARD, MIN, 0);
								state_autopilot = MOVE;
							}
							break;
						case 3:
							if(processMovement()){
								measure(ULTRASONIC, HEAD, HEAD_LEFT);
								chose_way = 0;
							}
							break;	
					}
					break;
				case OBSTACLE_SURFACE:
					switch(chose_way){
						case 0:
							if(processMovement()){
								if(turn_left){
									movement(LEFT, MIN, 222);
									setPositionDrive(HEAD,HEAD_LEFT);
									chose_way = 1;
								}
								else{
									movement(RIGHT, MAX, 222);
									setPositionDrive(HEAD,HEAD_RIGHT);
									chose_way = 1;
								}
							}
							break;
						case 1:
							if (turn_left)
								tmp1 = gettingADC(IR_ROBOT_4);
							else
								tmp1 = gettingADC(IR_ROBOT_3);	
							if((processMovement() == 1) || (tmp1 < 100)){
								LED(OFF,LED_RFM);
								LED(ON,LED_SCAN);
								LED(OFF, IR_ROBOT_3);
								LED(OFF, IR_ROBOT_4);
								onCheckCollision(FORWARD_CHECK);
								movement(FORWARD, MAX, 0);
								state_autopilot = MOVE;
							}
							break;
					}
			}
			break;
	}
}

//Установка состояния робота
void setStateRobot(StatesRobot_t set_state)
{
	//autopilot = 0;
	switch(set_state){
		case WAIT:
			stop();
			offCheckCollision();
			LED(OFF,LED_SCAN);
			LED(OFF,LED_RFM);
			//sprintf(status_robot,"Wait");
			break;
		case MOVE:
			LED(ON,LED_SCAN);
			LED(OFF,LED_RFM);
			//onCheckCollision(FORWARD);
			sprintf(status_robot,"Movement");
			break;
		case SCAN:
			LED(ON,LED_SCAN);
			LED(OFF,LED_RFM);
			stop();
			offCheckCollision();
			//sprintf(status_robot,"Scanning");
			break;
		case MEASURE:
			LED(ON,LED_SCAN);
			LED(OFF,LED_RFM);
			stop();
			offCheckCollision();
			//sprintf(status_robot,"Measure");
			break;
		case AUTO:
			LED(ON,LED_SCAN);
			LED(OFF,LED_RFM);
			//sprintf(status_robot,"Autopilot");
			onCheckCollision(FORWARD);
			state_autopilot = MOVE;
			movement(FORWARD,MIN,0);
			//autopilot = 1;
			break;
	}
	sendStrRFM("ok");
	state_robot = set_state;
}


//Обработчик запроса
void handlerQuery(char *query) 
{
	if(query != NULL){ 
		if(strncmp(query,"move",4) == 0){
			if (movementQuery(query)){	
				setStateRobot(MOVE);
				return;
			}
		}
		if(strncmp(query,"stop",4) == 0){
			setStateRobot(WAIT);
			return;
		}	
		
		if(strncmp(query,"scan",4) == 0){	
			scanningCurrent();
			setStateRobot(WAIT);
			return;
		}
		/*if(strncmp(query,"measure",7) == 0){
			if (measureQuery(query)){
				setStateRobot(MEASURE);
				return;
			}
		}*/
		/*if(strncmp(query,"status",6) == 0){	
			sendStrRFM(status_robot);
			return;
		}*/
		if(strncmp(query,"auto",4) == 0){	
			setStateRobot(AUTO);
			return;
		}
		sendStrRFM("unknown command");	
	}
}

//Обработчик запроса сканирования
uint8_t scanQuery(char *query_scan)
{
	char cmd[8];
	char target[8];
	if (sscanf(query_scan,"%s %s",cmd, target) == 2){
		if (strcmp(target,"space") == 0){
			scan(ULTRASONIC, HEAD);
			return 1;
		}
		if (strcmp(target,"surface") == 0){
			scan(INFRARED, CARRIAGE);
			return 1;
		} 	
	}
	return 0;	
}

//Обработчик запроса измерения
uint8_t measureQuery(char *query_measure)
{
	char cmd[8];
	char target[8];
	int position = 0;
	if (sscanf(query_measure,"%s %s %d",cmd, target, &position) == 3){
		if(position >= 0){
			if (strcmp(target,"space") == 0){
					measure(ULTRASONIC, HEAD, position);
					return 1;
			} 			
			if (strcmp(target,"surface") == 0){
				measure(INFRARED, CARRIAGE, position);
				return 1;
			} 
		}
	}
	return 0;		
}

//Обработчик запроса передвижения
uint8_t movementQuery(char *query_move)
{
	char cmd[8];
	char direct[8] = {'\0'};
	//int spd = 0;
	//int lim = 0;
	//if (sscanf(query_move,"%s %s %d %d",cmd, direct, &spd, &lim) == 4){
	if (sscanf(query_move,"%s %s",cmd, direct) == 2){	
			if (strcmp(direct,"forward") == 0){
					offCheckCollision();
					onCheckCollision(FORWARD_CHECK);
					movement(FORWARD,MIN,0);
					return 1;
			}
			if (strcmp(direct,"back") == 0){
					offCheckCollision();
					onCheckCollision(BACKWARD_CHECK);
					movement(BACKWARD,MIN,0);
					return 1;
			}
			if (strcmp(direct,"left") == 0){
					offCheckCollision();
					onCheckCollision(LEFT_CHECK);
					movement(LEFT,MIN,0);
					return 1;
			}
			if (strcmp(direct,"right") == 0){
					offCheckCollision();
					onCheckCollision(RIGHT_CHECK);
					movement(RIGHT,MIN,0);
					return 1;
			}
	}
	return 0;		
}
	
void scanningCurrent()
{
			const uint16_t  NUM = 200;
			uint8_t j = 0;
			uint16_t V[NUM];
			int tmp_V;
			char str_V[10];
			stop();
			for(j = 0; j < NUM; j++);
			LED(ON,LED_SCAN);
			movement(FORWARD,MAX,1);
			/*unsigned int timer = 0;
			TCCR1B |= (1<< CS10) |  (1<<CS12);*/	
			for(j = 0; j < NUM; j++)
				V[j] = gettingADC_10bit(1);
			LED(OFF,LED_SCAN);
			/*timer = TCNT1L;
			timer |= (TCNT1H << 8); 
			sprintf(str_V,"%d",timer);
			sendingStrUART(str_V);*/
			stop();
			
			uint8_t filter = 0;
			for (j = 0; j < NUM; j++){
				const uint8_t STEP_FILTER  = 3;
				switch(filter)
				{
					case 0:
							tmp_V =  V[j];
							if (V[j] > 5)
								filter = 1;
							break;
					case 1:
							if ((V[j] > V[j - 1] + STEP_FILTER) || (V[j] > V[j - 2] + STEP_FILTER) || (V[j] > V[j - 3] + STEP_FILTER)){
								V[j] = V[j - 1] + STEP_FILTER;
								break;
							}
							
							if ((V[j] < V[j - 1] - STEP_FILTER) || (V[j] < V[j - 2] - STEP_FILTER) || (V[j] < V[j - 3] - STEP_FILTER)){
								V[j]= V[j - 1] - STEP_FILTER; 
								break;	
							}
							break;
				}
			}
				
			for (j = 0; j < NUM; j++){
				if (j > 5){
					if (j < 194)
						tmp_V = (V[j] + V[j + 1] + V[j + 2] +  V[j + 3])/4;
					else
						tmp_V = (V[j] + V[j - 1] + V[j - 2] +  V[j - 3])/4;
				}
				else
					tmp_V = V[j];
				sprintf(str_V,"%d",tmp_V);
				sendingStrRFM(str_V);
			}
			//sendingStrRFM("ok");
}

Added src/firebot/RoboCar/src/RobotControl.h.























>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
#include <stdint.h>

#ifndef CONTROL_ROBOT_H
#define CONTROL_ROBOT_H

#define MES_RFM 11

//Главная функция управления роботом
void mainRobot();

#endif

Added src/firebot/RoboCar/src/Scanning subsystem/ADC.c.























































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
Студенческий клуб разработчиков компьютерных систем 
			Проект "Mr.General"

Модуль предназначен для управления АЦП.

Программа написана для микроконтроллера AVR ATmega 16.
Тактовая частота процессора - 8 МГц.

Для компиляции использовались инструменты Atmel AVR Studio 5
(Version 5.1.208).

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include "ADC.h"
#include <avr/interrupt.h>
#include <stdint.h>

//Запуск АЦП
void startADC(uint8_t channel_run)
{
	ADMUX = 1 << ADLAR | channel_run;
	//АЦП без прерываний
	ADCSRA = 1<<ADEN | 1 <<ADSC | 1<<ADPS2 | 1<<ADPS1 | 1<<ADPS0;	
}

//Возврат значения АЦП
uint8_t getADC ()
{
	//Ожидание конца преобразования
	while (ADCSRA & (1<<ADSC));
	return ADCH;
}

uint8_t gettingADC (uint8_t channel_run)
{
	ADMUX = 1 << ADLAR | channel_run;
	//АЦП без прерываний
	ADCSRA = 1<<ADEN | 1 <<ADSC | 1<<ADPS2 | 1<<ADPS1 | 1<<ADPS0;
	while (ADCSRA & (1<<ADSC));
	return ADCH;
}

uint16_t gettingADC_10bit (uint8_t channel)
{
	ADMUX = (0<<ADLAR) | channel;
	//АЦП без прерываний
	ADCSRA = 1<<ADEN | 1 <<ADSC | 1<<ADPS2 | 1<<ADPS1 | 1<<ADPS0;
	//Ожидание конца преобразования
	while (ADCSRA & (1<<ADSC));
	uint16_t resADC = 0;
	resADC = ADCL | (ADCH<<8);
	return resADC;
}

Added src/firebot/RoboCar/src/Scanning subsystem/ADC.h.







































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
	Студенческий клуб разработчиков компьютерных систем 
				Проект "Mr.General"

Это заголовочный файл к файлу ADC.c

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdint.h>

#ifndef ADC_H
#define ADC_H

/*
Запуск АЦП.
channel - канал  АЦП.
*/
void startADC(uint8_t channel);

/*
Возврат значения АЦП.
return - значение АЦП.
*/
uint8_t getADC ();

uint8_t gettingADC (uint8_t channel_run);

uint16_t gettingADC_10bit (uint8_t channel);

#endif

Added src/firebot/RoboCar/src/Scanning subsystem/CollisionAgent.c.

























































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
Студенческий клуб разработчиков компьютерных систем 
			Проект "Mr.General"

Модуль предназначен для обнаружения препядствий.

Программа написана для микроконтроллера AVR ATmega 16.
Тактовая частота процессора - 8 МГц.

Для компиляции использовались инструменты Atmel AVR Studio 5
(Version 5.1.208).

История изменений: 15.05.2014 - создан;

**********************************************************************/

#include <stdint.h>
#include "LED.h"
#include "ADC.h"
#include "Ultrasonic.h"
#include "ScanDrives.h"
#include "TimerScan.h"
#include "CollisionAgent.h"

#define  THRESHOLD_SURFACE 100
#define  THRESHOLD_SPACE_CM_MID 8
#define  THRESHOLD_SPACE_CM_MIN 9
#define  THRESHOLD_SPACE_CM_MAX 10

#define STEP_HEAD_MIN 3
#define STEP_HEAD_MID 5
#define STEP_HEAD_MAX 8

enum {
	LEFT_MIN_1,
	LEFT_MID_1,
	LEFT_MAX,
	LEFT_MID_2,
	LEFT_MIN_2,
	MID_1,
	RIGHT_MIN_1,
	RIGHT_MID_1,
	RIGHT_MAX,
	RIGHT_MID_2,
	RIGHT_MIN_2,
	MID_2
	 }positouns_head;

uint8_t sensor_surface;
DirectCollision_t current_derect_move;

uint8_t on_surface;
uint8_t on_space;
int8_t state_check_spase;

uint8_t pos_head, ctr_head;


void onCheckCollision(DirectCollision_t direct_move)
{
	offCheckCollision();
	on_surface = 0;
	on_space = 0;
	sensor_surface = 0;
	current_derect_move = direct_move;
	switch(current_derect_move){
		case FORWARD_CHECK:
			/*LED(ON,IR_ROBOT_1);
			LED(ON,IR_ROBOT_2);*/
			setPositionDrive(HEAD,HEAD_MID);
			startCtrScan(5);
			pos_head = LEFT_MIN_1;
			ctr_head = 0;
			state_check_spase = TURN_HEAD;
			on_space = 1;
			break;
		case LEFT_CHECK:
			/*LED(ON,IR_ROBOT_1);
			LED(ON,IR_ROBOT_2);
			LED(ON,IR_ROBOT_4);*/
			setPositionDrive(HEAD,HEAD_RIGHT);
			break;
		case RIGHT_CHECK:
			/*LED(ON,IR_ROBOT_1);
			LED(ON,IR_ROBOT_2);
			LED(ON,IR_ROBOT_3);*/
			setPositionDrive(HEAD,HEAD_LEFT);
			break;
		case BACKWARD_CHECK:
			/*LED(ON,IR_ROBOT_3);
			LED(ON,IR_ROBOT_4);*/
			break;
	}
}

//Проверка препядствий на поверхности
uint8_t isObstacleSurface()
{
	if(on_surface){
		switch(sensor_surface){
			case  0:
				switch(current_derect_move){
					case FORWARD_CHECK: case RIGHT_CHECK: case LEFT_CHECK:
						startADC(IR_ROBOT_1);
						break;
					case BACKWARD_CHECK:
						startADC(IR_ROBOT_3);
						break;	
				}
				sensor_surface = 1;
				break;
			case  1:
				switch(current_derect_move){
					case FORWARD_CHECK:
						startADC(IR_ROBOT_2);
						sensor_surface = 0;
						break;
					case LEFT_CHECK: case RIGHT_CHECK:
						startADC(IR_ROBOT_2);
						sensor_surface = 2;
						break;
					case BACKWARD_CHECK:
						startADC(IR_ROBOT_4);
						sensor_surface = 0;
						break;
				}
				break;
			case  2:
				switch(current_derect_move){
					case LEFT_CHECK:
						startADC(IR_ROBOT_4);
						break;
					case RIGHT_CHECK:
						startADC(IR_ROBOT_3);
						break;
				}
				sensor_surface = 0;		
				break;
		}
		if(getADC() < THRESHOLD_SURFACE)
			return 1;
	}
	return 0;
}

uint8_t isObstacleSpace()
{
	if(on_space){
		switch(state_check_spase){
			case CHECK:
				if(isMeasureUltrasonic()){
					float geting_value = 0;
					geting_value = getUltrasonic();
					if ((pos_head == MID_1) || (pos_head == MID_2)){
						if((geting_value <= THRESHOLD_SPACE_CM_MID) && (geting_value > 0))
							return 1;
					}
					else{
						if ((pos_head == RIGHT_MAX) || (pos_head == LEFT_MAX)){
							if((geting_value <= THRESHOLD_SPACE_CM_MAX) && (geting_value > 0))
								return 1;
						}
						else{
							if((geting_value <= THRESHOLD_SPACE_CM_MIN) && (geting_value > 0))
								return 1;	
						}
					}
					//if(ctr_head++ >= 3){
						switch(pos_head){
							case LEFT_MIN_1:
								setPositionDrive(HEAD, (HEAD_MID + STEP_HEAD_MIN));
								pos_head = LEFT_MID_1;
								break;
							case LEFT_MID_1:
								setPositionDrive(HEAD, (HEAD_MID + STEP_HEAD_MID));
								pos_head = LEFT_MAX;
								break;
							case LEFT_MAX:
								setPositionDrive(HEAD, (HEAD_MID + STEP_HEAD_MAX));
								pos_head = LEFT_MID_2;
								break;
							case LEFT_MID_2:
								setPositionDrive(HEAD, (HEAD_MID + STEP_HEAD_MID));
								pos_head = LEFT_MIN_2;
								break;	
							case LEFT_MIN_2:
								setPositionDrive(HEAD, (HEAD_MID + STEP_HEAD_MIN));
								pos_head = MID_1;
								break;	
							case MID_1:
								setPositionDrive(HEAD, HEAD_MID);
								pos_head = RIGHT_MIN_1;
								break;
							case RIGHT_MIN_1:
								setPositionDrive(HEAD, (HEAD_MID - STEP_HEAD_MIN));
								pos_head = RIGHT_MID_1;
								break;
							case RIGHT_MID_1:
								setPositionDrive(HEAD, (HEAD_MID - STEP_HEAD_MID));
								pos_head = RIGHT_MAX;
								break;		
							case RIGHT_MAX:
								setPositionDrive(HEAD, (HEAD_MID - STEP_HEAD_MAX));
								pos_head = RIGHT_MID_2;
								break;
							case RIGHT_MID_2:
								setPositionDrive(HEAD, (HEAD_MID - STEP_HEAD_MID));
								pos_head = RIGHT_MIN_2;
								break;		
							case RIGHT_MIN_2:
								setPositionDrive(HEAD, (HEAD_MID - STEP_HEAD_MIN));
								pos_head = MID_2;
								break;	
							case MID_2:
								setPositionDrive(HEAD, HEAD_MID);
								pos_head = LEFT_MIN_1;
								break;						
						}
						startCtrScan(3);
						ctr_head = 0;
						state_check_spase = TURN_HEAD;
					//}
					/*else{
							//startUltrasonic();
						startCtrScan(1);
						state_check_spase = TURN_HEAD;
					}*/
				}
				break;
			case TURN_HEAD:
				if(completeCtrScan()){
					startUltrasonic();
					state_check_spase = CHECK;
				}
				break;	
		}
	}
	return 0;
}

void offCheckCollision()
{
	/*LED(OFF,IR_ROBOT_1);
	LED(OFF,IR_ROBOT_2);
	LED(OFF,IR_ROBOT_3);
	LED(OFF,IR_ROBOT_4);*/
	on_surface = 0;
	on_space = 0;
}

Added src/firebot/RoboCar/src/Scanning subsystem/CollisionAgent.h.































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
	Студенческий клуб разработчиков компьютерных систем 
				Проект "Mr.General"

Это заголовочный файл к файлу CollisionAgent.с

История изменений: 15.05.2014 - создан;

**********************************************************************/

/*
Проверка препядствий на поверхности
return  - обнаружение препядствия
*/

typedef enum{FORWARD_CHECK = 1, BACKWARD_CHECK, LEFT_CHECK, RIGHT_CHECK}DirectCollision_t;

#define OBSTACLE_SURFACE 2
#define OBSTACLE_SPACE 3
#define TURN_HEAD 4
#define CHECK 5

/*
Запуск проверки столкновений.
direct_move - направление движения робота.
*/
void onCheckCollision(DirectCollision_t direct_move);

/*
Проверка наличия препядствий на поверхности.
return - 0 - нет припядствия, 1 - есть препядствие.
*/
uint8_t isObstacleSurface();

/*
Проверка наличия препядствий в пространстве.
return - 0 - нет припядствия, 1 - есть препядствие.
*/
uint8_t isObstacleSpace();

/*
Отключение проверки столкновений.
*/
void offCheckCollision();

Added src/firebot/RoboCar/src/Scanning subsystem/HeadDrive.c.









































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
Студенческий клуб разработчиков компьютерных систем 
			Проект "Mr.General"

Модуль предназначен для управления приводом головы (сервоприводом).

Программа написана для микроконтроллера AVR ATmega 16.
Тактовая частота процессора - 8 МГц.

Для компиляции использовались инструменты Atmel AVR Studio 5
(Version 5.1.208).

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <util/atomic.h>
#include <avr/interrupt.h>
#include "ScanDrives.h"

uint8_t current_position[2];

//Инициализация ШИМ для сервопривода, установка его в среднее положение
void initDrive(ScanDriver_t drive)
{
	const uint32_t FREQ_PWM_50HZ = 20000;
	switch(drive){
		case HEAD:
			// Значение периода ШИМ
			ICR1 = FREQ_PWM_50HZ;
			// Настраеваем таймер 1 на ШИМ 
			// COM1A1 - срброс при соврадении
			TCCR1A |= (1<<COM1A1) | (1<<WGM11);
			TCCR1B |= (1<<WGM13) | (1<<WGM12) | (1<< CS11);
			//OC1A настраеваем на выход
			DDRD |= (1<<5);
			setPositionHead(HEAD_MID);
			break;
		case CARRIAGE:
			;
			break;
	}
}

//Задание положения для сервопривода
void setPositionDrive(ScanDriver_t drive, uint8_t position)
{
	const uint16_t LONG_PULSE_LEFT_POSITION = 1150;
	const uint16_t LONG_PULSE_RIGHT_POSITION = 1950;
	const uint8_t STEP_POSITION = ((LONG_PULSE_RIGHT_POSITION - LONG_PULSE_LEFT_POSITION)/ (HEAD_RIGHT));
	switch(drive){
		case HEAD:
			if(position > HEAD_RIGHT)
				position = HEAD_RIGHT;
			if(position < HEAD_LEFT)
				position = HEAD_LEFT;
			ATOMIC_BLOCK (ATOMIC_RESTORESTATE){
				OCR1A = LONG_PULSE_LEFT_POSITION + (STEP_POSITION*position);
			}
			break;
		case CARRIAGE:
			;
			break;
	}
	current_position[drive] = position;
}

//Возврат положения привода
uint8_t getPositionDrive(ScanDriver_t drive)
{
	switch(drive){
		case HEAD:
			if(current_position[HEAD] >= HEAD_RIGHT)
				return FINAL;		
			break;
		case CARRIAGE:
			if(current_position[CARRIAGE] >= CARRIAGE_RIGHT)
				return FINAL;
			break;
	}
	return current_position[drive];	
}

uint8_t getTimeMoveDrive(ScanDriver_t chose_drive)
{
	const uint8_t TIME_POSITION_CARRIAGE = 10;
	const uint8_t TIME_POSITION_HEAD = 25;
	switch(chose_drive){
		case HEAD:
			return TIME_POSITION_HEAD;
			break;
		case CARRIAGE:
			return TIME_POSITION_CARRIAGE;
			break;
	}
	return 0;
}

Added src/firebot/RoboCar/src/Scanning subsystem/HeadDrive.h.































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
	Студенческий клуб разработчиков компьютерных систем 
				Проект "Mr.General"

Это заголовочный файл к файлу HeadDrive.c

История изменений: 08.11.2014 - создан;

**********************************************************************/

#ifndef HEAD_DRIVE_H
#define HEAD_DRIVE_H


enum positions_head {HEAD_LEFT = 0, HEAD_RIGHT = 16};
#define	HEAD_MID (HEAD_RIGHT/2)

enum positions_carriage {CARRIAGE_LEFT = 0, CARRIAGE_RIGHT = 16};
#define	CARRIAGE_MID (CARRIAGE_RIGHT/2)

typedef enum{HEAD, CARRIAGE}ScanDriver_t;

enum positions_scan {INITIAL = 0, MID = 254, FINAL = 255};

/*
Инициализация ШИМ для сервопривода, установка его в среднее положение.
*/
void initDrive(ScanDriver_t drive);

/*
Задание положения для сервопривода.
position - позиция сервопривода (от 0 до 16).
*/
void setPositionDrive(ScanDriver_t drive, uint8_t position);

/*
Возврат положения сервопривода.
return - позиция сервопривода (от 0 до 16).
*/
uint8_t getPositionDrive(ScanDriver_t drive);

uint16_t getTimeMoveDrive(ScanDriver_t drive);

#endif

Added src/firebot/RoboCar/src/Scanning subsystem/LED.c.





















































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
Студенческий клуб разработчиков компьютерных систем 
			Проект "Mr.General"

Модуль предназначен для управления светодиодами.

Программа написана для микроконтроллера AVR ATmega 16.
Тактовая частота процессора - 8 МГц.

Для компиляции использовались инструменты Atmel AVR Studio 5
(Version 5.1.208).

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include "LED.h"
#include <avr/interrupt.h>
#include <stdint.h>


void LED(Action_t action, Led_t led)
{
	switch (action){
		case OFF:
			switch(led){
				case IR_ROBOT_1:
					PORTC &= ~(1<<2);
					break;
				case IR_ROBOT_2:
					PORTA &= ~(1<<7);
					break;
				case IR_ROBOT_3:
					PORTA &= ~(1<<6);
					break;
				case IR_ROBOT_4:
					PORTA &= ~(1<<5);
					break;	
				case IR_CARRIAGE:
					PORTC &= ~(1<<1);
					break;
				case LED_SCAN:
					PORTD &= ~(1<<6);
					break;
				case LED_RFM:
					PORTD &= ~(1<<2);
					break;	
			}
			break;
		case ON:
			switch(led){
				case IR_ROBOT_1:
					DDRC |= (1<<2);
					PORTC |= (1<<2);
					break;
				case IR_ROBOT_2:
					DDRA |= (1<<7);
					PORTA |= (1<<7);
					break;
				case IR_ROBOT_3:
					DDRA |= (1<<6);
					PORTA |= (1<<6);
					break;
				case IR_ROBOT_4:
					DDRA |= (1<<5);
					PORTA |= (1<<5);
					break;	
				case IR_CARRIAGE:
					DDRC |= (1<<1);
					PORTC |= (1<<1);
					break;
				case LED_SCAN:
					DDRD |= (1<<6);
					PORTD |= (1<<6);
					break;
				case LED_RFM:
					DDRD |= (1<<2);
					PORTD |= (1<<2);
					break;	
			}
			break;
	}
}




Added src/firebot/RoboCar/src/Scanning subsystem/LED.h.















































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
	Студенческий клуб разработчиков компьютерных систем 
				Проект "Mr.General"

Это заголовочный файл к файлу Infrared.c

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdint.h>

#ifndef LED_H
#define LED_H

typedef enum {
	IR_ROBOT_1 = 3, 
	IR_ROBOT_2 = 2, 
	IR_ROBOT_3 = 1, 
	IR_ROBOT_4 = 0,
	IR_CARRIAGE = 4,
	LED_SCAN = 5,
	LED_RFM = 6
}Led_t;

typedef enum {OFF, ON}Action_t;

/*
Управление светодиодами.
action - действие над светодиодом.
led - выбор светодиода.
*/
void LED(Action_t action, Led_t led);


#endif

Added src/firebot/RoboCar/src/Scanning subsystem/ScanAgent.c.























































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
Студенческий клуб разработчиков компьютерных систем 
			Проект "Mr.General"

Модуль предназначен для управления измерением
и процессом сканирования.

Программа написана для микроконтроллера AVR ATmega 16.
Тактовая частота процессора - 8 МГц.

Для компиляции использовались инструменты Atmel AVR Studio 5
(Version 5.1.208).

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdio.h>
#include <stdint.h>
#include <util/atomic.h>
#include "TimerScan.h"
#include "ADC.h"
#include "LED.h"
#include "Ultrasonic.h"
#include "ScanDrives.h"
#include "ScanAgent.h"

/* 
Задание позиции носителя датчика.
chose_drive - выбор носителя;
set_position - задание позиция носителя.
*/
///void setPositionDrive(ScanDriver_t chose_drive, uint8_t set_position);

/*
Получение позиции носителя датчика.
drives_position - выбор носителя.
*/
///uint8_t getPositionDrive(ScanDriver_t chose_drive);

/*
Получение времени перемещения на соседнюю позицию носителя датчика.
chose_drive - выбор носителя.
*/
///uint16_t getTimeMoveDrive(ScanDriver_t chose_drive); */

/*
Задание измерения датчика.
chose_sensor - выбор датчика;
*/
void startSensing(Sensor_t chose_sensor);

/*
Получение результата измерения.
chose_sensor - выбор датчика;
return - значение измерения.
*/
char* getStrSensing(Sensor_t chose_sensor);

/*
Запись числа типа флоат в строку.
str - строка для записи;
value - значение числа;
precision -  количесво знаков после запятой.
*/
void float2str (char* str, float value, uint8_t precision);

/*
Возведение целого числа в положительную целую степень.
num - число для возвидения;
power - степень;
*/
int involution (uint8_t num, uint8_t power);


//Состояния конечного автомата
enum states {MEASURE, MOVEMENT_DRIVE, END_SCAN};

char ending_scan[] = "Scan complete";

uint8_t state_measure;				
uint8_t sensor;			
uint8_t state_scan;
uint8_t drive;

//Запуск процесса сканирования
void scan(uint8_t chose_sensor, ScanDriver_t chose_drive)
{
	drive = chose_drive;
	measure(chose_sensor, drive, 0);
	state_scan = MEASURE;
}

//Запуск измерения
void measure(uint8_t chose_sensor, ScanDriver_t chose_drive, uint8_t position)
{
	setPositionDrive(chose_drive, position);
	startCtrScan(getTimeMoveDrive(chose_drive));
	sensor = chose_sensor;
	state_measure = MOVEMENT_DRIVE;
}

//Получения результатов измерения
char* getStrMeasure()
{
	switch(state_measure){
		case MOVEMENT_DRIVE:
			if(completeCtrScan()){
				startSensing(sensor);
				state_measure = MEASURE;
			}
			break;
		case MEASURE:
			return getStrSensing(sensor);
			break;
	}
	return NULL;	
}

uint8_t readyDistance()
{
	static uint8_t ctr_measure = 0;
	switch(state_measure){
		case MOVEMENT_DRIVE:
			if(completeCtrScan()){
				startUltrasonic();
				state_measure = MEASURE;
				startCtrScan(5);
				ctr_measure = 0;
				//sendStrRFM("2.1");
			}
			break;
		case MEASURE:
			if (isMeasureUltrasonic()){
				//sendStrRFM("2.2");
				return	1;
			}
			
			/*if (completeCtrScan()){
				startUltrasonic();
				startCtrScan(2);
				if (++ctr_measure >= 1)
					return -1;
			}*/
			break;
	}
	return 0;
}

//Получения результатов процесса сканирования
char* getProcessScan()
{
	char* result_scan = NULL;
	switch(state_scan){
		case MEASURE:
			result_scan = getStrMeasure(sensor);
			if(result_scan != NULL){
				uint8_t current_position;
				current_position = getPositionDrive(drive);
				if (current_position != FINAL)
					measure(sensor, drive, ++current_position);
				else
					state_scan = END_SCAN;
			}
			return result_scan;
			break;
		case END_SCAN:
			return ending_scan;
			break;				
		
	}
	return NULL;
}

//Возврат сообщения окончания сканирования
char* getEndingScan()
{
	return ending_scan;
}

//Задание позиции носителя датчика
/* void setPositionDrive(ScanDriver_t chose_drive, uint8_t set_position)
{
	switch(chose_drive)
	{
		case HEAD:
			if(set_position >= HEAD_RIGHT)
				setPositionHead(HEAD_RIGHT);
			else
				setPositionHead(set_position);
			break;
		case CARRIAGE:
			;
			break;
	}					
}

//Получение позиции носителя датчика
uint8_t getPositionDrive(ScanDriver_t chose_drive)
{
	uint8_t position_drive;
	switch(chose_drive){
		case HEAD:
			position_drive = getPositionHead();
			if(position_drive >= HEAD_RIGHT)
				return FINAL;		
			break;
		case CARRIAGE:		
			return FINAL;	
			break;
	}
	return position_drive;	
}

//Получение времени перемещения на соседнюю позицию носителя датчика
uint16_t getTimeMoveDrive(ScanDriver_t chose_drive)
{
	const uint16_t TIME_POSITION_CARRIAGE = 1; 
	switch(chose_drive){
		case HEAD:
			return TIME_POSITION_HEAD;
			break;
		case CARRIAGE:
			return TIME_POSITION_CARRIAGE;
			break;
	}
	return 0;
} */

//Задание измерения
void startSensing(Sensor_t sensor_measure)
{
	switch (sensor_measure){
		case INFRARED:
			startADC(IR_CARRIAGE);
			break;	
		case ULTRASONIC:
			startUltrasonic();
			break;	
	}
}

//Получение результата измерения
char* getStrSensing(Sensor_t sensor_get)
{
	static char res_measure[8];
	switch(sensor_get){
		case INFRARED:
			if( getADC() != 0){
				sprintf(res_measure,"%d",  getADC());
				return res_measure;
			}
			break;
		case ULTRASONIC:
			if (isMeasureUltrasonic()){
				if(getUltrasonic() != -1)
					float2str(res_measure, getUltrasonic(), 2);
				else
					sprintf(res_measure,"%s", "NON");
				return res_measure;
			}
			break;
	}
	return NULL;
}


//Запись числа типа флоат в строку
void float2str (char* str, float value, uint8_t precision)
{
	int val_int = 0;
	int val_fraction = 0;
	val_int = value;
	ATOMIC_BLOCK (ATOMIC_RESTORESTATE){
		val_fraction = (value - val_int)*involution(10,precision);
	}
	sprintf(str,"%d.%d", val_int, val_fraction);
}

//Возведение целого числа в положительную целую степень
int involution (uint8_t num, uint8_t power)
{
	int res_raise = 0;
	res_raise = num;
	if (power != 0){
		uint8_t i;
		for (i = 1; i < power; ++i){
			res_raise *= num;
		}
		return res_raise;
	}
	else return 1;
}	



Added src/firebot/RoboCar/src/Scanning subsystem/ScanAgent.h.























































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
	Студенческий клуб разработчиков компьютерных систем 
				Проект "Mr.General"

Это заголовочный файл к файлу ScanAgent.с

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdint.h>
#include "ScanDrives.h"

#ifndef SCAN_AGENT_H
#define SCAN_AGENT_H


typedef enum{INFRARED, ULTRASONIC}Sensor_t;

/*
Запуск режима сканирования.
type_sensor - выбор датчика сканирования;
chose_drive - выбор носителя датчика сканирования.
*/
void scan(Sensor_t chose_sensor, ScanDriver_t chose_drive);


/*
Запуск измеения.
chose_sensor - выбор датчика измерения;
chose_drive - выбор носителя датчика измерения;
position - выбор позиции носителя датчика измерения.
*/
void measure(Sensor_t chose_sensor, ScanDriver_t chose_drive, uint8_t position);

/*
Получения результатов процесса сканирования.
return - результат измерения процесса сканирования.
*/
char* getProcessScan();

/*
Получения результата измерения.
return - результат измерения.
*/
char* getStrMeasure();

/*
Возврат сообщения окончания сканирования.
return - указатель на строку окончания сканирования.
*/
char* getEndingScan();

uint8_t readyDistance();

#endif

Added src/firebot/RoboCar/src/Scanning subsystem/ScanDrives.c.



















































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
Студенческий клуб разработчиков компьютерных систем 
			Проект "Mr.General"

Модуль предназначен для управления приводами для сканирования.

Программа написана для микроконтроллера AVR ATmega 16.
Тактовая частота процессора - 8 МГц.

Для компиляции использовались инструменты Atmel AVR Studio 5
(Version 5.1.208).

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <util/atomic.h>
#include <avr/interrupt.h>
#include "ScanDrives.h"

uint8_t current_position[2];

//Инициализация ШИМ для сервопривода, установка его в среднее положение
void initDrive(ScanDriver_t drive)
{
	const uint32_t FREQ_PWM_50HZ = 20000;
	switch(drive){
		case HEAD:
			// Значение периода ШИМ
			ICR1 = FREQ_PWM_50HZ;
			// Настраеваем таймер 1 на ШИМ 
			// COM1A1 - срброс при соврадении
			TCCR1A |= (1<<COM1A1) | (1<<WGM11);
			//пределитель 8
			TCCR1B |= (1<<WGM13) | (1<<WGM12) | (1<< CS11);
			//OC1A настраеваем на выход
			DDRD |= (1<<5);
			setPositionDrive(HEAD,HEAD_MID);
			break;
		case CARRIAGE:
			;
			break;
	}
}

//Задание положения для сервопривода
void setPositionDrive(ScanDriver_t drive, uint8_t position)
{
	const uint16_t LONG_PULSE_LEFT_POSITION = 1150;
	const uint16_t LONG_PULSE_RIGHT_POSITION = 1950;
	const uint8_t STEP_POSITION = ((LONG_PULSE_RIGHT_POSITION - LONG_PULSE_LEFT_POSITION)/ (HEAD_RIGHT));
	//const uint16_t LONG_PULSE_LEFT_POSITION = 1950;
	//const uint16_t LONG_PULSE_RIGHT_POSITION = 1150;
	//const uint8_t STEP_POSITION = ((LONG_PULSE_LEFT_POSITION - LONG_PULSE_RIGHT_POSITION)/ (HEAD_RIGHT));
	switch(drive){
		case HEAD:
			if(position > HEAD_RIGHT)
				position = HEAD_RIGHT;
			if(position < HEAD_LEFT)
				position = HEAD_LEFT;
			ATOMIC_BLOCK (ATOMIC_RESTORESTATE){
				OCR1A = LONG_PULSE_LEFT_POSITION + (STEP_POSITION*position);
				//OCR1A = LONG_PULSE_RIGHT_POSITION + (STEP_POSITION*position);
			}
			break;
		case CARRIAGE:
			;
			break;
	}
	current_position[drive] = position;
}

//Возврат положения привода
uint8_t getPositionDrive(ScanDriver_t drive)
{
	switch(drive){
		case HEAD:
			if(current_position[HEAD] >= HEAD_RIGHT)
				return FINAL;		
			break;
		case CARRIAGE:
			if(current_position[CARRIAGE] >= CARRIAGE_LEFT)
				return FINAL;
			break;
	}
	return current_position[drive];	
}

uint8_t getTimeMoveDrive(ScanDriver_t drive)
{
	const uint8_t TIME_POSITION_CARRIAGE = 10;
	const uint8_t TIME_POSITION_HEAD = 10;
	switch(drive){
		case HEAD:
			return TIME_POSITION_HEAD;
			break;
		case CARRIAGE:
			return TIME_POSITION_CARRIAGE;
			break;
	}
	return 0;
}

Added src/firebot/RoboCar/src/Scanning subsystem/ScanDrives.h.



















































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
	Студенческий клуб разработчиков компьютерных систем 
				Проект "Mr.General"

Это заголовочный файл к файлу HeadDrive.c

История изменений: 08.11.2014 - создан;

**********************************************************************/

#ifndef HEAD_DRIVE_H
#define HEAD_DRIVE_H


#define HEAD_RIGHT 16
#define HEAD_LEFT 0
#define	HEAD_MID (HEAD_RIGHT/2)

#define CARRIAGE_RIGHT 20
#define CARRIAGE_LEFT 0
#define	CARRIAGE_MID (HEAD_RIGHT/2)


typedef enum{HEAD, CARRIAGE}ScanDriver_t;

enum positions_scan {INITIAL = 0, MID = 254, FINAL = 255};

/*
Инициализация привода.
drive - выбор привода.
*/
void initDrive(ScanDriver_t drive);

/*
Установка привода в заданное положение.
drive - выбор привода.
position - положения привода.
*/
void setPositionDrive(ScanDriver_t drive, uint8_t position);

/*
Получение текущего положения привода.
drive - выбор привода.
return - положение привода.
*/
uint8_t getPositionDrive(ScanDriver_t drive);

/*
Получение время позиционирования привода.
drive - выбор привода.
*/
uint8_t getTimeMoveDrive(ScanDriver_t drive);

#endif

Added src/firebot/RoboCar/src/Scanning subsystem/TimerScan.c.



















































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
Студенческий клуб разработчиков компьютерных систем 
			Проект "Mr.General"

Модуль предназначен для управления счетчиком сканирования.

Программа написана для микроконтроллера AVR ATmega 16.
Тактовая частота процессора - 8 МГц.

Для компиляции использовались инструменты Atmel AVR Studio 5
(Version 5.1.208).

Используемые ресурсы микроконтроллера:
* Таймера общего назначения TIM1;
* Прерывание TIMER0_OVF_vect;

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <avr/interrupt.h>
#include <stdint.h>
#include <util/atomic.h>
#include "TimerScan.h"


static uint8_t ctr_scan;
static uint8_t complete_ctr_scan;

//Запуск счетчика
void startCtrScan(uint8_t value)
{
	ctr_scan = value;
	complete_ctr_scan = 0;
	//Прерываниe по переполнению TIM1
	TIMSK |= (1<<TOIE1);	
}

//Возврат окончания счета
uint8_t completeCtrScan()
{
	return complete_ctr_scan;
}

//Вектор прерывания по переполнению TIM1
ISR(TIMER1_OVF_vect)
{
	if(--ctr_scan == 0){
		complete_ctr_scan = 1;
		// Отключение прерываниe по переполнению TIM1
		TIMSK &= ~(1<<TOIE1);
	}
}

Added src/firebot/RoboCar/src/Scanning subsystem/TimerScan.h.









































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
	Студенческий клуб разработчиков компьютерных систем 
				Проект "Mr.General"

Это заголовочный файл к файлу TIMER.c

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdint.h>


#ifndef TIMER_H
#define TIMER_H

/*
Запуск счетчика.
chose_ctr - выбор счетчика;
value - значение счетчика.
*/
void startCtrScan(uint8_t value);

/*
Возврат окончания счета.
chose_ctr - выбор счетчика.
return - значение счетчика.
*/
uint8_t completeCtrScan();



#endif

Added src/firebot/RoboCar/src/Scanning subsystem/UART.c.











































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
Студенческий клуб разработчиков компьютерных систем 
			Проект "Mr.General"

Модуль предназначен для обмена данными по UART.

Программа написана для микроконтроллера AVR ATmega 16.
Тактовая частота процессора - 8 МГц.

Для компиляции использовались инструменты Atmel AVR Studio 5
(Version 5.1.208).

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <avr/interrupt.h>
#include <avr/io.h>
#include <stdint.h>
#include <stdio.h>
#include "UART.h"

#define F_CPU 8000000 
// Скорость обмена
#define BAUDRATE 9600
#define BAUDDIVIDER F_CPU/16/BAUDRATE-1

#define SIZE_MESSEGE 5
#define SIZE_BUFRX 3
#define SIZE_BUFTX 5

void addStrTransmit(char *add_str);
char* takeStrTransmit();


static char buffer_RX[SIZE_BUFRX][SIZE_MESSEGE];
static uint8_t busy_str_RX = 0;
static uint8_t empty_str_RX = 0;

static char *ptr_TX = NULL;
static char *buffer_TX[SIZE_BUFTX] = {NULL};
static uint8_t empty_TX = 0;
static uint8_t take_TX = 0;

static uint8_t busyUART = 0;
static uint8_t transmiting = 0;


// Добавление строки в буффер для передачи
void addStrTransmit(char *add_str)
{
	buffer_TX[empty_TX++] = add_str;
	if (empty_TX >= SIZE_BUFTX){
		empty_TX = 0;
	}	
	/*if (empty_TX == take_TX)
		ptr_TX = "ERROR SIZE_BUFTX UART";*/
}

// Взятие строки из буффера для передачи
char* takeStrTransmit()
{ 
	if(take_TX >= SIZE_BUFTX){
		take_TX = 0; 
	}	
	if(take_TX == empty_TX){
		return NULL;
	}	
	return buffer_TX[take_TX++];
}

// Поставка строки в очередь для передачи данных, запуск передачи
void sendStrUART (char *str_send)
{
	if (str_send != NULL){
		if (!transmiting){
			ptr_TX = str_send;
			transmiting = 1;
		} else
			addStrTransmit(str_send);
	}
}

// Управление процессом передачи данных
void processTransmitUART()
{ 
	if((transmiting) && (!busyUART)){
		if (*ptr_TX == '\0'){
			busyUART = 1;
			UDR = '\r';
			ptr_TX = takeStrTransmit();
			if(ptr_TX == NULL){
				transmiting = 0;
			}	
		} else {
			busyUART = 1;
			UDR = *ptr_TX++;
		}
	}	
}

// Управление процессом приема данных
void processReceiveUART ()
{
	static uint8_t empty_char_RX = 0;
	buffer_RX[empty_str_RX][empty_char_RX] = UDR; 	
	if (buffer_RX[empty_str_RX][empty_char_RX] == '\r'){
		buffer_RX[empty_str_RX][empty_char_RX] = '\0';
		if (++empty_str_RX >= SIZE_BUFRX){
			empty_str_RX = 0;
		}	
		/*if (empty_str_RX >= busy_str_RX)
			sendStrUART("ERROR SIZE_BUFRX UART");*/
		empty_char_RX = 0;
		busyUART = 0;
	} 
	else {
		if(++empty_char_RX >= SIZE_MESSEGE){
				empty_char_RX = 0;
				//sendStrUART("ERROR SIZE_MESSEGE UART");
		}
		busyUART = 1;
	}
}

char *getStrUART ()
{	
	if(busy_str_RX >= SIZE_BUFRX){
		busy_str_RX = 0; 
	}	
	if(busy_str_RX == empty_str_RX){
		return NULL;
	}	
	return buffer_RX[busy_str_RX++];
}

// Прирывание вызваное приходом данных 
ISR(USART_RXC_vect)
{	
	processReceiveUART ();
}

// Прирывание вызваное отправкой данных 
ISR(USART_TXC_vect)
{	
	busyUART = 0;
}	

void initUART()
{
	// Установка BAUDRATE
	UBRRH = (uint8_t)((BAUDDIVIDER) >> 8);
	UBRRL = (uint8_t)(BAUDDIVIDER);
	// Запуск приемника и передатчика, разрешение прерываний
	// после приема 
	UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE)| (1 << TXCIE) ;
	// Установка формата: 8 бит + 1 стопбит
	UCSRC = (1 << URSEL )| (1 << UCSZ0) | (1 << UCSZ1);
}



Added src/firebot/RoboCar/src/Scanning subsystem/UART.h.





























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
	Студенческий клуб разработчиков компьютерных систем 
				Проект "Mr.General"

Это заголовочный файл к файлу UART.c

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdint.h>

#ifndef UART_TX_RX_H
#define UART_TX_RX_H

#define NUMBER_BATES_RX 1
#define NUMBER_BATES_TX 1


/*
Инициализация UART.
*/
void initUART();

/*
Отправка данных. 
str - указатель на строку для отправки по UART.
*/
void sendStrUART (char *str);

/*
Прием данных. 
return - указатель на строку пришедшую по UART.
*/
char* getStrUART ();

// Управление процессом передачи данных
void processTransmitUART();

// Управление процессом приема данных
void processReceiveUART ();

#endif

Added src/firebot/RoboCar/src/Scanning subsystem/Ultrasonic.c.











































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
Студенческий клуб разработчиков компьютерных систем 
			Проект "Mr.General"

Модуль предназначен для управления ультразвуковым датчиком.

Программа написана для микроконтроллера AVR ATmega 16.
Тактовая частота процессора - 8 МГц.

Для компиляции использовались инструменты Atmel AVR Studio 5
(Version 5.1.208).

Используемые ресурсы микроконтроллера:
* Порт D - выводы 3, 4;
* Таймера общего назначения TIM2;
* Прерывание INT1_vect, TIMER2_OVF_vect;

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <avr/interrupt.h>
#include "Ultrasonic.h"

#define TRIG 4
#define MAX_TIMER_VALUE 255
#define F_TIM_MHZ 8
#define PRESCALER_TIM 1
enum statesUS {BEGIN_PULSE,END_PULSE};
uint16_t ctr_intrpt;
uint8_t complete_measureUS;
float distance_cm;
uint8_t start_value, finish_value, timer_value, stateUS = BEGIN_PULSE;


//Запуск измерения УЗ датчиком.
void startUltrasonic()
{
	complete_measureUS = 0;
	stateUS = BEGIN_PULSE;
	ctr_intrpt = 0;
	//Обнуление выхода УЗ дачтика для начала измерения
	PORTD &= ~(1<<TRIG);
}

//Получение значения измерения
float getUltrasonic()
{
	if ((distance_cm < 0) || (distance_cm > 400))
		return 0;
	return distance_cm;
}

uint8_t isMeasureUltrasonic()
{
	return complete_measureUS;
}

//Вектор прерывания, возникающее в результате изменении уровня входного сигнала на ножке INT1(см. Даташит)
ISR(INT1_vect)
{	
	timer_value = TCNT2;
	switch (stateUS){
	case BEGIN_PULSE:
		//Запуск прерываний по переполнению TIM2
		TIMSK |= (1<<TOIE2);
		start_value = timer_value;
		stateUS = END_PULSE;
		break;
	case END_PULSE:
		//Установка выхода УЗ дачтика
		PORTD |= (1<<TRIG);
		//Отключение прерываний по переполнению TIM2
		TIMSK &= ~(1<<TOIE2);
		finish_value = timer_value;
		if (ctr_intrpt != 0){
			distance_cm = ((MAX_TIMER_VALUE - start_value) + finish_value + (MAX_TIMER_VALUE * (ctr_intrpt-1))) / PRESCALER_TIM / F_TIM_MHZ / 58.0;
		}
		else{
			distance_cm = (finish_value - start_value) / PRESCALER_TIM / F_TIM_MHZ / 58.0;
		}
		complete_measureUS = 1;
		stateUS = BEGIN_PULSE;
		break;	
	}
}

//Вектор прерывания, возникающее в результате переполнения TIM2
ISR(TIMER2_OVF_vect)
{
	ctr_intrpt++;
}

//Инициализация ультразвукового датчика
void initUltrasonic()
{
	//Установка выхода УЗ дачтика
	DDRD |= (1<<TRIG);
	PORTD |= (1<<TRIG);
	// Прирывания при изменении сигнала на ножке INT1
	MCUCR |= (1<<ISC10);
	//while(!(GIFR & (1<<INTF1)));
	//GIFR = (1<<INTF1);
	// Разрешение прирывания при изменении сигнала на ножке INT1
	GICR |= (1<<INT1);
}








Added src/firebot/RoboCar/src/Scanning subsystem/Ultrasonic.h.













































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/**********************************************************************

					НТУ "ХПИ"
Кафедра "Автоматизированные электромеханические системы"
	Студенческий клуб разработчиков компьютерных систем 
				Проект "Mr.General"

Это заголовочный файл к файлу ULTRASONIC.c

История изменений: 08.11.2014 - создан;

**********************************************************************/

#include <stdint.h>

#ifndef HEAD_CONTROL_H
#define HEAD_CONTROL_H


//Инициализация ультразвукового датчика.
void initUltrasonic();

//Запуск измерения УЗ датчика.
void startUltrasonic();

/*
Получения состояния измерения.
return – 1- измерение завершено, 0 – измерение не завершено.
*/
uint8_t isMeasureUltrasonic();

/*
Получения значения измерения.
return - значение измерения.
*/
float getUltrasonic();

#endif